如何通过两个独立的查询依赖于父查询通过mongoose查询?

var EmpSchema = {_id:String, empName:String} var ProjectSchema = {_id:String, projectName} var reportSchema = {empId:String, projectId:String, comments:String} //These are two many to many relations 

现在,当我使用mongoose报告架构和存储empId,empName,projectId,projectName,每个报告数组中的评论,我越来越不一致。

 var showDetails = [] reportModel.find({}, function(err, reps){ var dispItem = {}; reps.forEach(function(value, index, arr){ //querying empColl empModel.findOne({value.empId},function(err, emp){ dispItem["empName"] = emp.empName; }); //querying projectColl projectModel.findOne({value.projectId},function(err, pro){ dispItem["projectName"] = pro.projectName; }); dispItem["comments"] = pro.comments; showDetails.push(dispItem); }); res.end(showDetails); }); 

请忽略任何语法错误。 我在这里要问的是两个callback查询empColl和projectColl是独立的,并被同时触发。 所以数据不能在showDetails中正确显示。 我试图嵌套这两个查询,也没有工作(不一致)。 也许诺言是要走的路? (新承诺)

嵌套调用应该有助于构build每个视图。

但是在res.end(showDetails);之前,你需要一些方法来检测它们什么时候完成res.end(showDetails); 你可以用一个计数器来做到这一点:

 var showDetails = [] reportModel.find({}, function(err, reps){ var numLeft = reps.length; reps.forEach(function(value, index, arr){ //querying empColl empModel.findOne({_id : value.empId},function(err, emp){ projectModel.findOne({_id : value.projectId},function(err, pro){ showDetails.push({ empName : emp.empName, projectName : pro.projectName, comments : pro.comments }); if ( --$numLeft === 0 ) { res.end(showDetails); } }); }); }); }); 

或者承诺的方式:

 var repsPromises = []; reportModel.find({}, function(err, reps){ var repDefer = Q.defer(); repsPromises.push(repDefer.promise); reps.forEach(function(value, index, arr){ var empDefer = Q.defer(); var proDefer = Q.defer(); //querying empColl empModel.findOne({value.empId},function(err, emp){ if ( err ) { empDefer.reject(err); } else { empDefer.resolve(emp); } }); //querying projectColl projectModel.findOne({value.projectId},function(err, pro){ if ( err ) { proDefer.reject(err); } else { proDefer.resolve(pro); } }); Q.all([empDefer.promise, proDefer.promise]) .then( function (emp, pro) { repDefer.resolve({ empName : emp.empName, projectName : pro.projectName, comments : pro.comments }); }, function (err) { console.log("The first error encountered was: "+err); repDefer.reject(err); } ); }); }); Q.all(repsPromises) .then( function () { res.end(Array.prototype.slice.call(arguments, 0)); }, function (err) { console.log("The first error encounter was: "+err); } );