如何在NodeJS中的forEach中正确使用异步

时间:2018-09-01 05:11:29

标签: javascript node.js express asynchronous async-await

我正在使用此forEach循环将一些数据推入数组并将其发送到客户端

   var arrayToSend = []  //Empty Array

   SomeArray.forEach(function(item){
        Collection.findById(item.id,function (err,data) {
          if (err) {
            console.log(err)
          } else {

            arrayToSend.push(data.record)
          }
  //How can I run this next line at end of loop  asynchronously
         res.render("index",{arrayToSend : arrayToSend })
        })
      })


    }

如何在forEach范围内以回调形式在循环结束后使用异步运行 res.render(“ index”,{arrayToSend:arrayToSend}),否则,如果我在循环会发送空数组吗?

1 个答案:

答案 0 :(得分:1)

使用.forEach代替.map,将someArray中的每个项目映射到一个Promise,以便您可以创建一个Promises数组。如果在该数组上调用Promise.all,则将获得一个Promise,该诺言将在数组中的所有promise都解决后解决。

由于findById是基于回调的,而不是基于Promise的,因此您需要先将每个回调转换为Promise:

const promises = someArray.map((item) => new Promise((resolve, reject) => {
  Collection.findById(item.id, (err,data) => {
    if (err) return reject(err);
    resolve(data.record);
  });
}));
Promise.all(promises)
  .then(arrayToSend => {
    res.render("index", { arrayToSend });
  })
  .catch((err) => {
    // handle errors
  });

如果您想容忍来自findById的错误并且仍然构建arrayToSend而没有出现错误的项目,则可以push到外部阵列(类似于您最初的操作) )和resolve无条件判断,findById是否导致错误:

const arrayToSend = [];
const promises = someArray.map((item) => new Promise((resolve, reject) => {
  Collection.findById(item.id, (err,data) => {
    if (err) console.log(err);
    else arrayToSend.push(data.record);
    resolve();
  });
}));
Promise.all(promises)
  .then(() => {
    res.render("index", { arrayToSend });
  })