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);
});
请忽略任何语法错误。我在这里要问的是查询empColl和projectColl的两个回调是独立的并且同时被解雇了。所以showDetails中的数据不正确。 我尝试嵌套两个查询,这也没有工作(不一致)。也许承诺是要走的路? (承诺的新手)
答案 0 :(得分:2)
嵌套调用应该有助于构建每个dispItem。
但是你需要一些方法来检测它们在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);
}
);