Javascript 返回从循环中调用的DB查询检索到的数据时出现问题
我在循环中执行多个mongoDB查询。并且希望将所有结果作为一个数据数组发送。但是当我简单地使用return来发送数据时,它只返回未定义的结果,而不等待所有DB请求的结果。我也试着使用q.Molde,但问题是一样的 代码:Javascript 返回从循环中调用的DB查询检索到的数据时出现问题,javascript,node.js,mongodb,promise,q,Javascript,Node.js,Mongodb,Promise,Q,我在循环中执行多个mongoDB查询。并且希望将所有结果作为一个数据数组发送。但是当我简单地使用return来发送数据时,它只返回未定义的结果,而不等待所有DB请求的结果。我也试着使用q.Molde,但问题是一样的 代码: var getPrayerInCat = function(data){ var result ; var finalData = []; if(data.length >0){ data.forEach(functio
var getPrayerInCat = function(data){
var result ;
var finalData = [];
if(data.length >0){
data.forEach(function(data2){
var id= data2.id;
Prayer.find({prayerCat:id},function(err,prayer){
var deferred = Q.defer()
if (err) { // ...
console.log('An error has occurred');
// res.send(err);
result= finalData = err
} else {
if(!prayer){
// console.log(data2.id+'--0');
data2.prayersCount = 0;
result = deferred.resolve(finalData.push(data2))
} else {
// console.log(data2.id+'--'+prayer.length);
data2.prayersCount = prayer.length;
// console.log(prayer)
result = deferred.resolve(finalData.push(data2))
} // else for data forward
}
deferred.promise;
})
// deferred.resolve(finalData);
})
/*if(finalData.length > 0) { return finalData;}*/
}
}
finalData返回时未定义。让我们从使用承诺的一般规则开始: 每个执行异步操作的函数都必须返回一个承诺 在您的案例中,这些功能是什么?这是
getPrayerInCat
,forEach
回调和Prayer.find
嗯,Prayer.find
不会返回承诺,它是一个库函数,所以我们不能修改它。规则2开始发挥作用:
对于每个不可用的函数
在我们的案例中,这很容易:
现在我们只有承诺,不再需要任何延期。第三条规则开始发挥作用:
所有使用异步结果执行操作的操作都会进入。然后回调
…并返回结果。该死,如果“某物”是异步的,那么这个结果甚至可以是一个承诺!这样,我们就可以编写完整的回调函数:
function getPrayerCount(data2) {
var id = data2.id;
return find({prayerCat:id})
// ^^^^^^ Rule 1
.then(function(prayer) {
// ^^^^^ Rule 3
if (!prayer)
data2.prayersCount = 0;
else
data2.prayersCount = prayer.length;
return data2;
// ^^^^^^ Rule 3b
});
}
现在,我们有一些更复杂的东西:一个循环。反复调用getrajercount()
将得到多个承诺,这些承诺的异步任务并行运行,并以未知顺序解析。我们希望等待所有这些,也就是说,当每项任务完成后,得到一个解决所有结果的承诺
对于如此复杂的任务,不要试图提出自己的解决方案:
检查库的API
在那里我们发现,正是这一点。编写getrajerincat
现在很容易:
function getPrayerInCat(data) {
var promises = data.map(getPrayerCount); // don't use forEach, we get something back
return Q.all(promises);
// ^^^^^^ Rule 1
}
如果我们需要对
Q.all
解析为的数组执行任何操作,只需应用规则3即可。这是一个承诺。我可以删除它,我正试图解决这个问题,所以我尝试了这个方法。您的函数getprayrincat()
不返回任何内容,也不向回调返回任何内容。此外,如果您从代码中删除注释并更新帖子以包含您的例外输出,这也会很有帮助。如果你被退回延期代码>,而不是仅仅显示它?我认为finalData是未定义的,因为它是在从延迟对象填充之前被访问的。@MuddassirKhanani:Afair,Q
没有molde
方法。什么意思?您在代码中的何处使用了它?我已经使用了您的代码,但相同的问题是返回表单find,不要等待db的resukt。因此最终的结果是未定义的。getrajercat(“”).then(function(data){getrajerincat(data)})。then(function(data2){console.log(data2)})var getrajerincat=function(data){var结果;var finalData=[];if(data.length>0){var promises=data.map(getrajercount);返回Q.all(promises)}函数getpraircount(data2){var id=data2.id;返回find({praircat:id})。然后(函数(prair){if(!prair)data2.prairscount=0;else data2.prairscount=prair.length;返回data2;});}您忘记了回调中的规则1,然后
回调。它需要是getrajercat(“”)。然后是(函数(数据){
返回
getrajercat(数据);})。然后是(…)
。在不返回任何内容的情况下,promise解析为undefined
…这次我又遇到了同样的问题@Bergi又添加了一个循环
function getPrayerInCat(data) {
var promises = data.map(getPrayerCount); // don't use forEach, we get something back
return Q.all(promises);
// ^^^^^^ Rule 1
}