0

我正在开发一个角度应用程序并且遇到了问题。我对 JS 很陌生,对异步编程也很陌生,所以我猜我错过了一些明显的东西。

问题的要点是我有一个构建数组的 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]

可以看到 after 循环输出首先执行。据我所知,它第一次输出 Array[1] 时实际上并没有填充该数组 - chrome 只是在事后填充它。“分配后的str”行后面的空白行是我尝试输出显然不起作用的连接的地方。然后最后执行循环中的代码。正如我所提到的,我需要确保在 for 循环完成填充数组之后发生数组连接。

4

2 回答 2

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;
       }
      });
    }
}
于 2012-12-04T04:53:02.850 回答
0

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

于 2013-01-16T21:17:51.813 回答