使用异步并行进行多个mongoose调用

时间:2015-08-11 10:35:45

标签: node.js asynchronous mongoose

一段时间以来一直在努力,我似乎​​错过了一些非常明显的东西。举个例子。让我们说我想要并行进行三次调用。为了使它成为一个简单的例子,或者易于测试,我们想要一个从mongodb中获取以下信息的脚本。

我们希望找到以下信息: - 我们想列出每个索引的ns - 我们想列出拥有_id的用户 - 我们想列出每个拥有密钥的索引的ns (是的,你是对的,这是一组荒谬的查询,但它们会在每个mongo数据库上返回一些东西。)

因此,在mongo db上执行此操作的简单脚本是:

var mongoose = require("mongoose");
var morgan = require('morgan');             // log requests to the console (express4)
var async = require('async');
mongoose.connect('mongodb://localhost/admin');



var Indexes = mongoose.model('system.indexes', {
    name: String,
    ns: String
});
var Users = mongoose.model('system.users', {
    user: String
})


        Indexes.find().exec(function(err, docs){
            for( var doc in docs ){
                console.log("Got Index " + docs[doc].ns);
            }
        })
        Users.find({ _id: {$ne: null}}).exec(function(err, docs){
            for (var doc in docs){
                console.log("And user " + docs[doc].user );
            }
        })
        Indexes.find({ key : {$ne : null}}).exec(function(err, docs){
            for (var doc in docs) {
                console.log("And Index with a key " + docs[doc].ns);
            }
        })

但是如果我想使用异步,我该怎么做呢? 所以尝试以下方法并行运行它们:

var mongoose = require("mongoose");
var morgan = require('morgan');             // log requests to the console (express4)
var async = require('async');
mongoose.connect('mongodb://localhost/admin');



var Indexes = mongoose.model('system.indexes', {
    name: String,
    ns: String
});
var Users = mongoose.model('system.users', {
    user: String
})


/// So lets do it with async Map instead
var queries = [];
queries.push(Indexes.find().exec());
queries.push(Users.find({ _id: {$ne: null}}).exec());
queries.push(Indexes.find({ key : {$ne : null}}).exec());

async.parallel(queries, function(err, docs){
    console.log("I've done some stuff");
})

这给了我一个错误陈述

  

任务(_restParam(function(err,args){               ^ TypeError:object不是函数

但有一个简单的方法。如何使用异步映射或并行进行多个查找。

=====关于Jigars的优秀回复,我们更接近答案===== Jigars现在很好的答案,保持下面的东西 如果有人遇到同样的问题

/// So lets do it with async Map instead
var queries = [];
queries.push(function (cb) {
    try {
        result = Indexes.find().exec();
        cb(null, result);
    } catch(e) {
        cb(e);
    }
})

queries.push(function (cb) {
    try {
        result = Users.find({ _id: {$ne: null}}).exec();
        cb(null, result);
    } catch(e) {
        cb(e);
    }
})

queries.push(function (cb) {
    try {
        result = Indexes.find({ key : {$ne : null}}).exec();
        cb(null, result);
    } catch(e) {
        cb(e);
    }
})

async.parallel(queries, function(err, docs) {
    // if any query fails
    if (err) {
        throw err;
    }

    var res1 = docs[0]; // result of queries[0]
    for (var opts in res1){
        console.log("In res1 we got " + res1[opts])
    }
    var res2 = docs[1]; // result of queries[1]
    for (var opts in res2){
        console.log("In res2 we got " + res2[opts])
    }
    var res3 = docs[2]; // result of queries[2]
    for (var opts in res3){
        console.log("In res3 we got " + res3[opts])
    }
})

所以并行工作现在,只是没有返回我想要的。 res1,res2和res3的结果看起来像js代码:

2 个答案:

答案 0 :(得分:5)

您的queries.push命令应采用以下方式

queries.push(function (cb) {
    Indexes.find().exec(function (err, docs) {
        if (err) {
            throw cb(err);
        }

        // do some stuff with docs & pass or directly pass it
        cb(null, docs);
    });
})    

queries.push(function (cb) {
    Users.find({ _id: {$ne: null}}).exec(function (err, docs) {
        if (err) {
            throw cb(err);
        }

        // do some stuff with docs & pass or directly pass it
        cb(null, docs);
    });
})

queries.push(function (cb) {
    Indexes.find({ key : {$ne : null}}).exec(function (err, docs){
        if (err) {
            throw cb(err);
        }

        // do some stuff with docs & pass or directly pass it
        cb(null, docs);
    });
})

async.parallel(queries, function(err, docs) {
    // if any query fails
    if (err) {
        throw err;
    }

    var res1 = docs[0]; // result of queries[0]
    var res2 = docs[1]; // result of queries[1]
    var res3 = docs[2]; // result of queries[2]
})

async将多个函数与回调函数作为参数。每个功能完成后,您需要调用cb。 您还需要传递每个查询的结果值。当所有查询完成并行执行

时,将以数组形式返回给您

答案 1 :(得分:0)

我们可以像下面的代码一样使用 async/await。

let queries = [];
    
      userIds.forEach(userId => {
        queries.push(async()=>await Users.find({_id:userId}))
      });
    
      Promise.all( queries).then(function(result) {
          // result is an array of responses here
          console.log("result", result);
          return result;
      }).catch(function(err) {
          console.log(err);
          return ;
      });