我正在研究一个有角度的应用程序并遇到问题。我对JS很新,对asynch编程很新,所以我猜我错过了一些明显的东西。
问题的关键是我有一个构建数组的for循环。然后我需要在for循环完成它的业务后立即加入该数组。通常,这将是一个没有脑子,但显然是角度的for循环异步执行。我需要在 for循环退出后强制我的数组连接发生。
if(!data.results[i].is_deleted) {
var objectsOnCurrentPermission = new Array();
if(data.results[i].objects) {
for(var j = 0; j < data.results[i].objects.length; j++) {
var currentObjectId = data.results[i].objects[j].object_id;
var currentObjectName;
var objectData = Object.get({id: currentObjectId}, function(objectData) {
objectsOnCurrentPermission.push(objectData.name);
console.log('in loop in get fn');
console.log(objectsOnCurrentPermission);
});
}
console.log('after loop');
console.log(objectsOnCurrentPermission);
var listOfObjectsOnCurrentPermission = objectsOnCurrentPermission.join(', ');
console.log('str after assignment');
console.log(listOfObjectsOnCurrentPermission);
data.results[i]['objects_list'] = listOfObjectsOnCurrentPermission;
}
令我惊讶的是,当我检查输出时,我看到了(为了便于阅读,我添加了'&lt;'s)
after loop permissions.js:246
>Array[1]
permissions.js:247
str after assignment permissions.js:249
permissions.js:250
in loop in fn permissions.js:242
>Array[1]
您可以看到后循环输出首先执行。据我所知,第一次输出Array [1]时,数组实际上并没有被填充 - chrome只是在事后填充它。在“分配后的str”行之后的空行是我尝试输出显然不起作用的连接的地方。然后最后循环中的代码执行。正如我所提到的,我需要确保在for循环完成填充数组之后发生数组连接。
答案 0 :(得分:3)
根据您的console.log()
输出,似乎Object.get()
函数必须是异步的,这意味着调用它只是启动它的执行,并在一段时间后完成。据推测,当它完成时,它会调用你传递的回调函数。
因此,要完成最终结果的处理,您需要在最后一次Object.get()
调用完成后触发最终代码 - 当调用所有Object.get()
完成回调时。一个简单的计数器可以跟踪剩余的数量,这是一种简单的方法。
以下是关于如何跟踪所有.get()
方法何时完成然后触发最终代码的基本概念:
if(!data.results[i].is_deleted) {
var objectsOnCurrentPermission = [];
if(data.results[i].objects) {
// initialize counter so we know when all async functions are done
var numRemaining = data.results[i].objects.length;
for(var j = 0; j < data.results[i].objects.length; j++) {
var currentObjectId = data.results[i].objects[j].object_id;
var currentObjectName;
var objectData = Object.get({id: currentObjectId}, function(objectData) {
objectsOnCurrentPermission.push(objectData.name);
console.log('get complete fn called');
console.log(objectsOnCurrentPermission);
--numRemaining;
if (numRemaining === 0) {
console.log('all get() functions done');
console.log(objectsOnCurrentPermission);
var listOfObjectsOnCurrentPermission = objectsOnCurrentPermission.join(', ');
console.log('str after assignment');
console.log(listOfObjectsOnCurrentPermission);
data.results[i]['objects_list'] = listOfObjectsOnCurrentPermission;
}
});
}
}
答案 1 :(得分:0)
我最终使用caolan的异步库来管理我的同步/异步代码需求。特别是async.parallel允许我构建中间数组并确保它们在继续之前完成。 https://github.com/caolan/async