我在循环中进行多个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返回时未定义.

推荐答案

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

Every function that does something asynchronous must return a promise

在你的 case 中,这些功能是什么?getPrayerInCat分,forEach分,Prayer.find分.

嗯,Prayer.find不会返回promise ,它是一个库函数,所以我们不能修改它.规则2开始发挥作用:

100 for every function that doesn't

在我们的例子中,Q's node-interfacing helpers很简单:

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

现在我们只有promise ,不再需要任何延期.第三条规则开始发挥作用:

Everything that does something with an async result goes into a 100 callback

…并返回结果.该死,如果"某物"是异步的,那么这个结果甚至可以是一个promise !有了这个,我们可以编写完整的回调函数:

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 ,这些promise 的异步任务并行运行,并以未知顺序解析.我们希望等待所有这些,也就是说,当每项任务完成后,得到一个解决所有结果的promise .

对于这样复杂的任务,不要试图想出自己的解决方案:

Check the API of your library

在那里我们找到了Q.all个,正是这个.写作getPrayerInCat现在很容易:

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.

Mongodb相关问答推荐

在MogoDB中按时间间隔分组、统计文档和获取间隔时间

如何对嵌套在另一个数组中的数组中的字段执行查找?

无法从我的NextJS 14应用程序中的Redux工具包2.0中提取数据

将消息流式传输到WebSocket

使用golang中的过滤器从mongodb复合集合中获取所有数据

Mongo:查找具有 0 个关联文档的文档,成本更低

在 MongoDB 中使用 findOneAndUpdate 有条件地更新/更新嵌入式数组

有没有办法在 Prisma for MongoDB 的模式中显式声明 int32?

以聚合顺序使用 $$ROOT

Raft Vs MongoDB 初选

node.js & express - 应用程序 struct 的全局模块和最佳实践

使用 Spring Boot >= 2.0.1.RELEASE 将 ZonedDateTime 保存到 MongoDB 时出现 CodecConfigurationException

mongodb上不区分大小写的查询

Mongoose:填充填充字段

mongodb中类型不相等的查询

无法从 MongoDb C# 中的 BsonType ObjectId 反序列化字符串

MongoDB - 文件大小巨大且不断增长

如何为 node.js 中的 MongoDB 索引指定 javascript 对象中的属性顺序?

移动 MongoDB 的数据文件夹?

未找到 MongoDB 数据/数据库