2012-12-04 38 views
0

我正在研究一个角度的应用程序,并遇到问题。我对JS非常陌生,对异步编程非常陌生,所以我猜测我错过了一些明显的东西。For循环异步

问题的要点是我有一个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; 
} 

令我惊讶的是,当我检查输出我看到(我加了'<的提高可读性)

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] 

你可以看到,执行第一循环后输出。从我所知道的,第一次输出数组[1]时,数组实际上并没有被填充 - 事实上,chrome只是填充它。在表示“str分配后”的行之后的空行是我试图输出连接的那个空行,这显然不起作用。然后最后执行循环中的代码。正如我所提到的,我需要确保在for循环完成填充数组之后发生数组连接。

+0

你看过Angular的$ q吗? (至少对我来说)这已经优雅地解决了我的异步问题。 –

回答

0

我结束了使用caolan的异步库来管理我的同步/异步代码需要。特别是async.parallel允许我构建中间数组并确保它们在完成之前完成。 https://github.com/caolan/async

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