简体   繁体   English

返回从循环中调用的数据库查询中检索的数据的问题

[英]Issue in returning data retrieved from DB queries called in the loop

I making multiple mongoDB queries in loop. 我在循环中进行多个mongoDB查询。 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. 并且想要将所有结果作为一个数据数组发送。但是当我简单地使用return来发送数据时,它只返回undefined而不等待所有数据库请求的结果。 I also tried to use q.moulde but same issue. 我也尝试过使用q.moulde但同样的问题。

Code: 码:

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 is returned undefined. finalData返回undefined。

Let's start with the general rule for using promises: 让我们从使用promises的一般规则开始:

Every function that does something asynchronous must return a promise 每个执行异步操作的函数都必须返回一个promise

Which functions are these in your case? 在你的情况下,这些功能是什么? It's getPrayerInCat , the forEach callback, and Prayer.find . 它是getPrayerInCatforEach回调和Prayer.find

Hm, Prayer.find doesn't return a promise, and it's a library function so we cannot modify it. 嗯, Prayer.find不返回一个promise,它是一个库函数,所以我们不能修改它。 Rule 2 comes into play: 规则2发挥作用:

Create an immediate wrapper for every function that doesn't 为每个没有的函数创建一个立即包装器

In our case that's easy with Q's node-interfacing helpers : 在我们的例子中, Q的节点接口助手很容易:

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 使用异步结果执行某些操作的所有内容都会转换为.then回调

…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
    });
}

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. 反复调用getPrayerCount()将获得多个promise,其异步任务并行运行并以未知顺序解析。 We want to wait for all of them - ie 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: 对于这些复杂的任务,不要试图提出自己的解决方案:

Check the API of your library 检查您的库的API

And there we find Q.all , which does exactly this. 在那里我们找到Q.all ,它正是这样做的。 Writing getPrayerInCat is a breeze now: 现在写getPrayerInCat是一件轻而易举的事:

function getPrayerInCat(data) {
    var promises = data.map(getPrayerCount); // don't use forEach, we get something back
    return Q.all(promises);
//  ^^^^^^ Rule 1
}

If we needed to do anything with the array that Q.all resolves to, just apply Rule 3. 如果我们需要对Q.all解析的数组做任何事情,只需应用规则3。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM