调用异步函数时如何给数组赋值?
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
});
我正在使用 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
});