调用异步函数时如何给数组赋值?

How to assign an array when calling asynchronous functions?

我正在使用 AngularJS 和 Angular Translate。我有一个包含 '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;
    });
} 

函数执行后存储在translatedObjects数组中的结果是:

[null,null,null,"This is Hat in English"]

我猜这是因为我实际上正在执行对 $translate 服务的异步调用,而 translatedObject[i] 实际上并没有指向正确的对象,因为 'i' 没有在当前上下文。

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

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

for (var i = 0; i < objects.length; i++) {
    $translate(objects[i].key).then(function (translation) {
        $scope.translatedObjects.push(translation);
    });
} 

是的,当回调触发时,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));
} 

上面发生的事情是您创建了一个接受参数的匿名函数,x,return是一个回调函数。因此,当您调用传递 i=0 的函数时,它将 return 一个回调函数,该回调函数可以从创建它的范围访问 x=0 。下一次迭代时,匿名函数会被再次调用,return一个新的回调函数,其中x为1,以此类推

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

您已经在使用 promises,所以您可以使用 Promise.all():

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
});