返回从循环中调用的数据库查询中检索到的数据的问题 [英] Issue in returning data retrieved from DB queries called in the loop

查看:22
本文介绍了返回从循环中调用的数据库查询中检索到的数据的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在循环中进行了多个 mongoDB 查询.并希望将所有结果作为一个数据数组发送.但是当我简单地使用 return 发送数据时,它只是返回 undefined 并且不等待所有 DB 请求的结果.我也尝试使用 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.

推荐答案

让我们从使用 Promise 的一般规则开始:

Let's start with the general rule for using promises:

每个执行异步操作的函数都必须返回一个承诺

在您的情况下,这些功能是什么?它是 getPrayerInCatforEach 回调和 Prayer.find.

Which functions are these in your case? It's getPrayerInCat, the forEach callback, and Prayer.find.

嗯,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:

为不支持的每个函数创建一个立即包装器

在我们的例子中,使用 Q 的节点接口助手:

In our case that's easy with Q's node-interfacing helpers:

var find = Q.nbind(Prayer.find, Prayer);

现在我们只有 Promise,不再需要任何 deferred.第三条规则发挥作用:

Now we have only promises around, and do no more need any deferreds. Third rule comes into play:

所有对异步结果执行的操作都会进入 .then 回调

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆