循环内的异步调用

时间:2012-09-18 07:19:58

标签: node.js asynchronous express

  

可能重复:
  Coordinating parallel execution in node.js

首先,动手伪代码:

forEach(arrayelements) {
  asyncQueryFunction(function(qres) {
    //work with query results.
  });
}
// finally, AFTER all callbacks did return:
res.render("myview");

怎么做?

如果不够清楚,我会解释:

我需要进行一系列“更新”查询(在mongodb中,通过mongoose),循环遍历文档ID列表。对于我的数组中的每个id,我将调用一个异步函数,它将返回查询结果(实际上我不需要对它们做任何事情)。

我知道我必须使用.forEach() javascript循环,但是如果我的所有异步查询都完成了,我怎样才能执行“最终”回调?

当我有一系列“有限”的任务要执行时,我已经在使用优秀的异步库(https://github.com/caolan/async)来完成这类任务。但我不认为我可以传递一系列不同的功能。

我能吗?

2 个答案:

答案 0 :(得分:9)

非常简单的模式是使用'运行任务'计数器:

var numRunningQueries = 0
forEach(arrayelements) {
  ++numRunningQueries;
  asyncQueryFunction(function(qres) {
    //work with query results.
    --numRunningQueries;
    if (numRunningQueries === 0) {
       // finally, AFTER all callbacks did return:
       res.render("myview");
    }
  });
}

或者,使用异步帮助程序库,例如Async.js

答案 1 :(得分:2)

如果我理解正确,asyncQueryFunction始终是相同的,就像您对每个文档应用相同的更新一样。

我使用辅助方法在保存(只是交换更新)多个mongoose文档后进行回调(从CoffeeScript转换,所以它可能不完美):

function saveAll(docs, callback) {

  // a count for completed operations, and save all errors
  var count = 0
    , errors = [];

  if (docs.length === 0) {
    return callback();
  } else {
    for (var i = 0; i < docs.length; i++) {

      // instead of save, do an update, or asyncQueryFunction
      docs[i].save(function(err) {

        // increase the count in each individual callback
        count++;

        // save any errors
        if (err != null) {
          errors.push(err);
        }

        // once all the individual operations have completed,
        // callback, including any errors
        if (count === docs.length) {
          return callback(errors);
        }
      });
    }
  }
};

saveAll(arrayElements, function(errors) {
  // finally, AFTER all callbacks did return:
  res.render("myview");
}