返回从循环中调用的数据库查询中检索的数据的问题 [英] Issue in returning data retrieved from DB queries called in the loop
问题描述
我在循环中进行多个mongoDB查询。并且想要将所有结果作为一个数据数组发送。但是当我简单地使用return来发送数据时,它只返回undefined而不等待所有数据库请求的结果。我也试过使用q.moulde但同样的问题。
I making multiple mongoDB queries in loop. and want to send the all results as one data array.But when I simple use the return for send the data it simply return undefined and do not wait for results of all DB request. I also tried to use q.moulde but same issue.
代码:
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。
finalData is returned undefined.
推荐答案
让我们从使用promises的一般规则开始:
Let's start with the general rule for using promises:
执行异步操作的每个函数都必须返回一个承诺
您的案例中有哪些功能?它是 getPrayerInCat
, forEach
回调, Prayer.find
。
Which functions are these in your case? It's getPrayerInCat
, the forEach
callback, and Prayer.find
.
Hm, Prayer.find
没有返回一个承诺,它是一个库函数,所以我们无法修改它。规则2发挥作用:
Hm, Prayer.find
doesn't return a promise, and it's a library function so we cannot modify it. Rule 2 comes into play:
Create an immediate wrapper for every function that doesn't
在我们的情况下,使用< a href =https://github.com/kriskowal/q/wiki/API-Reference#qnbindnodemethod-thisarg-args\"rel =nofollow noreferrer> Q的节点接口助手:
In our case that's easy with Q's node-interfacing helpers:
var find = Q.nbind(Prayer.find, Prayer);
现在我们只有承诺,不再需要任何延期。第三条规则发挥作用:
Now we have only promises around, and do no more need any deferreds. Third rule comes into play:
使用异步结果执行某些操作的所有内容都会进入
。然后
回调
Everything that does something with an async result goes into a
.then
callback
...并返回结果。地狱,如果某事是异步的,那么结果甚至可以成为一种承诺!有了这个,我们可以编写完整的回调函数:
…and returns the result. Hell, that result can even be a promise if "something" was asynchronous! With this, we can write the complete callback function:
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
});
}
现在,我们有一些更复杂的东西:一个循环。反复调用 getPrayerCount()
将获得多个promise,其异步任务并行运行并以未知顺序解析。我们希望等待所有这些 - 即获得一个承诺,当每个任务完成时,它会解决所有结果。
Now, we have something a bit more complicated: a loop. Repeatedly calling getPrayerCount()
will get us multiple promises, whose asynchronous tasks run in parallel and resolve in unknown order. We want to wait for all of them - i.e. get a promise that resolves with all results when each of the tasks has finished.
对于这些复杂的任务,不要尝试提出自己的解决方案:
For such complicated tasks, don't try to come up with your own solution:
检查您图书馆的API
我们发现 Q.all
,就是这样做的。写 getPrayerInCat
现在是轻而易举的事了:
And there we find Q.all
, which does exactly this. Writing getPrayerInCat
is a breeze now:
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.
If we needed to do anything with the array that Q.all
resolves to, just apply Rule 3.
这篇关于返回从循环中调用的数据库查询中检索的数据的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!