2017-04-05 103 views
0

我有以下两个Monogoose型号:的Node.js - 等待所有Model.find()来完成

ClanMember: tag:String, name:string; 
War: members:Array; #array of tags 

我目前通过查找当前成员的数组:

ClanMember.find({ 
    'tag': { 
     $in: memberTags #an array of tags 
    } 
}).limit(memberTags.length) 
    .exec(function(err, members) { 

} 

由此我想执行War.find() S和添加信息的每一个成员的文档,所以像这样的:

ClanMember.find({ 
    'tag': { 
     $in: memberTags 
    } 
}).limit(memberTags.length) 
    .exec(function(err, members) { 

    var MemberArray = []; 
    for (var member in members) { 
     if (members.hasOwnProperty(member)) { 
      var currentMember = members[member]; 
      War.find({members: currentMember.tag}).exec(function(err, wars) { 
       currentMember.wars = wars; 
       MemberArray.push(currentMember); 
      }); 
     } 
    } 

    #I WANT TO RENDER HERE 

}); 

后这一切都发生了,我想给会员的对象(与战争对象)的全新数组传递给一个观点:

res.render('members', { 
     members: MemberArray, 
    }); 

什么是确保所有War.find()函数中找到的最好办法并在将数组传递给渲染函数之前完成执行?

回答

3

为此,您必须使用承诺。代码应该如下所示。

var Promise = require('promise'); 
ClanMember.find({ 
    'tag': { 
     $in: memberTags 
    } 
}).limit(memberTags.length) 
    .exec(function(err, members) { 
    var promises = []; 
    var MemberArray = []; 
    members.forEach((member)=>{ 
      var currentMember = member; 
      let warPromise = War.find({members: currentMember.tag}).exec().then(function(wars) { 
       currentMember.wars = wars; 
       MemberArray.push(currentMember); 
       return true; 
      }).catch(function(err){ 
       throw err; 
      }); 
      promises.push(warPromise); 
     } 
    }); 


    Promise.all(promises).then(function(result){ 
     #I WANT TO RENDER HERE 

     }).catch(function(err){ 

     }); 

}); 

在这里Promise.all()函数将确保所有先前的承诺已完成。然后你可以给予回应。

+0

请选择我的答案 –

+0

谢谢。然而,这对我来说并不完美。 'warPromise'中的'currentMember'变量始终是数组中最后一个'member'元素。如果我'console.log(currentMember.tag')'相同的标记得到返回.. – GarethPrice

+0

我编辑了我的答案,它现在将工作..作为你在发现战争时使用回调语法。我已将其转换为承诺。请现在试试。 –