具有回调的Node.js for循环,之后同步执行

时间:2016-02-16 11:46:17

标签: javascript node.js

我遇到了Nodejs的情况,其中有一个带回调函数的for循环。在数组上调用循环,对于每个值,使用查询调用更新操作,并将该值替换为查询结果。

结构是这样的:

console.log(body);

for (var i = 0; i < body.length; i++) {
    console.log(body[i]);
    QueryManager.query(lookup_query, [body[i]], function (err, query_result) {
        if (err) {
            console.log('Query failed', err);
            return;
        }

        query_result = JSON.parse(query_result);

        if(query_result.matrics.resultCount == 1)
            body[i] = query_result.results[0].id;

        console.log("Array value replaced for position:" + i);
    });
}

console.log("Array updated!");

for循环可以通过异步执行完成,然后它应该等待所有回调完成。因此,在完全更新数组后,下一个语句应该同步。

因此跟踪循环的控制台输出应该按以下顺序排列:

["1","2","3","4","5"]
Array value replaced for position:0
Array value replaced for position:1
Array value replaced for position:3
Array value replaced for position:2
Array value replaced for position:4
Array updated!

除了第一个和最后一个输出之外,输出之间可以是任何顺序。

我怎样才能做到这一点?

修改 整个事情都在http服务器请求中。所以我得到的数组来自用户的POST。根据数组中提供的键将每个值映射到实际值。在数组中将所有值从其键替换为值之后,我需要根据该值准备一些外部数据。然后在该请求的响应中将该数据发送回用户。

因此,在整个请求完成并发送响应之前,不应阻止请求线程。它应该准备好听取新的请求。

2 个答案:

答案 0 :(得分:1)

使用async.forEachLimit,limit = 1。

示例:

var tempArray = [1, 2, 3, 4, 5];

async.forEachLimit(tempArray, 1, function(no, callback) {
    console.log("Current number : " + no);
    callback();
}, function(error){
    callback(error);
});

此代码将打印如下:

当前号码:1

当前号码:2

当前号码:3

当前号码:4

当前号码:5

答案 1 :(得分:0)

基本上Promise.all等待集合中的所有承诺解决,然后它会自行解析调用.then()

console.log(body);

var promiseCollection = [];
for (var i = 0; i < body.length; i++) {
    console.log(body[i]);
    promiseCollection.push(new Promise(function (resolve, reject) {
      QueryManager.query(lookup_query, [body[i]], function (err, query_result) {
          if (err) {
              console.log('Query failed', err);
              reject(weFailedAndCanReturnWhy);
              return;
          }

          query_result = JSON.parse(query_result);

          if(query_result.matrics.resultCount == 1)
              body[i] = query_result.results[0].id;

          console.log("Array value replaced for position:" + i);
          resolve(canReturnStuffHere);
      })})
    );
}

Promise.all(promiseCollection)
  .then(function(){
    console.log("Array updated!");
  });