2017-04-05 105 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

我編輯了我的答案,它現在將工作..作爲你在發現戰爭時使用回調語法。我已將其轉換爲承諾。請現在試試。 –