Javascript 调用异步函数时如何分配数组?

Javascript 调用异步函数时如何分配数组?,javascript,arrays,angularjs,asynchronous,angular-translate,Javascript,Arrays,Angularjs,Asynchronous,Angular Translate,我正在使用AngularJS和。我有一个具有“key”属性的对象数组——一个应该转换的字符串 这是我的对象数组: var objects = [{ id: 1, key: 'Jacket' }, { id: 2, key: 'Trousers' }, { id: 3, key: 'Hat' }]; 以下是我的翻译: var translationsEN = { Ja

我正在使用AngularJS和。我有一个具有“key”属性的对象数组——一个应该转换的字符串

这是我的对象数组:

var objects = [{
        id: 1,
        key: 'Jacket'
    }, {
        id: 2,
        key: 'Trousers'
    }, {
        id: 3,
        key: 'Hat'
    }];
以下是我的翻译:

var translationsEN = { 
    Jacket: 'This is Jacket in English',
    Trousers: 'This is Trousers in English',
    Hat: 'This is Hat in English'
}
当某些特定事件发生时,我需要一个对象数组,但需要翻译,而不是键。这就是为什么我有一个函数可以执行以下操作:

var translatedObjects = [];

for (var i = 0; i < objects.length; i++) {
    $translate(objects[i].key).then(function (translation) {
        translatedObjects[i] = translation;
    });
} 
我想这是因为我实际上正在执行对$translate服务的异步调用,而translateObject[I]实际上没有指向正确的对象,因为“I”在当前上下文中没有定义


那么,如何执行异步函数调用并按照上面的示例适当地分配数组?

您可以使用数组的
push
方法插入数据。不需要传递
i
,因为它将以相同的顺序插入

for (var i = 0; i < objects.length; i++) {
    $translate(objects[i].key).then(function (translation) {
        $scope.translatedObjects.push(translation);
    });
} 
for(var i=0;i
是,当回调触发时,for循环将完成,
i
的值将为
3
。然后,这三个回调将覆盖同一索引中的值三次

您可以将变量封装在新范围中:

for (var i = 0; i < objects.length; i++) {
    $translate(objects[i].key).then((function(x) { 
        return function (translation) {
           translatedObjects[x] = translation;
        };
    })(i));
} 
for(var i=0;i
上面所做的是创建一个匿名函数,该函数接受一个参数
x
,并返回一个回调函数。因此,当调用传递
i=0
的函数时,它将返回一个回调函数,该函数可以从创建它的作用域访问
x=0
。在下一次迭代中,将再次调用匿名函数,并返回一个新的回调函数,其中
x
为1,以此类推


如果您知道回调将被同步调用,并且只想分配给数组,那么ngLover的答案可能更具可读性。

您已经在使用承诺,因此可以使用:

var承诺=[];
对于(var i=0;i
for循环不会等待非同步操作完成。是的,我可以做些什么来实现我期望的结果?通过递归调用函数,您可以实现它。这里是否保证翻译字符串的顺序?如果第一次调用
$translate()
比第二次调用花费更多的时间怎么办?@ShanShan ya shaan如果$translate执行异步任务,那么david使用闭包的方法是正确的。我更喜欢我的
承诺。尽管所有的
解决方案都更干净,嵌套更少,但OP做出了选择:D
for (var i = 0; i < objects.length; i++) {
    $translate(objects[i].key).then((function(x) { 
        return function (translation) {
           translatedObjects[x] = translation;
        };
    })(i));
} 
var promises = [];
for (var i = 0; i < objects.length; i++) {
    promises.push($translate(objects[i].key));
}

Promise.all(promises).then(function (translatedObjects) {
    // use your array here
});