首页 > 解决方案 > 执行forEach循环后如何将数组作为输出返回?

问题描述

我有一个数组,其中项目 _id 存储在用户集合中。我最初是在获取该数组,然后我试图检索与存储在项目集合中的 _id (存储在用户集合中)相对应的数据。检索到的数据被推送到数组中,并且该数组作为输出返回。但我无法这样做。正在返回一个空数组。

var projectInfo= new Array();

users.post('/retrieveProjects', function(user, res, next) { 
  MongoClient.connect(url, function(err,db) {
    if (err) throw err;
    var dbo = db.db("EMWorks");
    dbo.collection("users").findOne({_id:user.body.userid})
    .then(response => {
      if(response)
      {
        console.log(response);
        (response.project).forEach(element => {
          dbo.collection("projects").findOne({_id:element})
          .then(respo => {
            console.log(respo);
            projectInfo.push(respo);
          });
          console.log(projectInfo) ;
        });

      }else{
        console.log("No Projects created yet...!");
      }
    });
  });
});

代码的输出

标签: reactjsmongodbmongoose

解决方案


问题是它dbo.collection("projects").findOne是异步的并返回一个承诺。forEach 循环运行并为每个元素生成这些承诺,但不等待其执行。当循环结束并返回一个空数组时,promise 不会被解析。您可以等待 promise 被执行,然后才返回数组:

const promises = [];
(response.project).forEach(element => {
      promises.push(dbo.collection("projects").findOne({_id:element})
      .then(respo => {
        console.log(respo);
        projectInfo.push(respo);
      });
    }));
   Promise.all(promises).then(function(values) {
      console.log(projectInfo) ;
 });

这也可以使用 map 函数和 async/await 来简化:

const promises = (response.project).map(async element => {
      const respo  = await dbo.collection("projects").findOne({_id:element});
      projectInfo.push(respo);
    });
   Promise.all(promises).then(function(values) {
      console.log(projectInfo) ;
 });

推荐阅读