Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/405.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 返回从循环中调用的DB查询检索到的数据时出现问题_Javascript_Node.js_Mongodb_Promise_Q - Fatal编程技术网

Javascript 返回从循环中调用的DB查询检索到的数据时出现问题

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

我在循环中执行多个mongoDB查询。并且希望将所有结果作为一个数据数组发送。但是当我简单地使用return来发送数据时,它只返回未定义的结果,而不等待所有DB请求的结果。我也试着使用q.Molde,但问题是一样的

代码:

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
}