Node.js - 等待多个异步调用

War*_*ald 33 javascript mongodb node.js

我在渲染Jade模板之前尝试制作多个MongoDB查询,但是我无法弄清楚如何在渲染模板之前等待所有Mongo查询完成.

exports.init = function(req, res){


    var NYLakes = {};
    var NJLakes = {};
    var filterNY = {"State" : "NY"};
    db.collection('lakes').find(filterNY).toArray(function(err, result) {
        if (err) throw err;
        NYLakes = result;
    });

    var filterNJ = {"State" : "NJ"};
    db.collection('lakes').find(filterNJ).toArray(function(err, result) {
        if (err) throw err;
        NJLakes = result;
    });

    res.render('explore/index', {
            NYlakes: NYLakes,
            NJlakes: NJLakes
    });

};
Run Code Online (Sandbox Code Playgroud)

小智 56

我是下划线/ lodash的忠实粉丝,所以我经常使用它_.after,它会创建一个只在被调用一定次数后执行的函数.

var finished = _.after(2, doRender);

asyncMethod1(data, function(err){
  //...
  finished();
});

asyncMethod2(data, function(err){
  //...
  finished();
})

function doRender(){
  res.render(); // etc
} 
Run Code Online (Sandbox Code Playgroud)

由于javascript提升了使用function funcName()语法定义的函数的定义,因此您的代码自然会读取:从上到下.


Chr*_*res 18

假设您希望并行运行这两个操作而不是等待一个操作在开始下一个操作之前完成,那么您需要跟踪每个回调中已完成的操作数.

在raw node.js javascript中,一种方法是这样做:

exports.init = function(req, res){
    var NYLakes = null;
    var NJLakes = null;
    var filterNY = {"State" : "NY"};

    db.collection('lakes').find(filterNY).toArray(function(err, result) {
        if (err) throw err;
        NYLakes = result;
        complete();
    });

    var filterNJ = {"State" : "NJ"};
    db.collection('lakes').find(filterNJ).toArray(function(err, result) {
        if (err) throw err;
        NJLakes = result;
        complete();
    });

    function complete() {
        if (NYLakes !== null && NJLakes !== null) {
            res.render('explore/index', {
                NYlakes: NYLakes,
                NJlakes: NJLakes
            });
        }
    }

};
Run Code Online (Sandbox Code Playgroud)

基本上这里发生的是你在每个操作结束时检查是否所有操作都已完成,并且此时你完成了操作.

如果您正在做很多这些事情,请查看异步库作为工具的示例,以便更轻松地管理此类事情.


S.D*_*.D. 6

您可以使用异步模块:

var states = [{"State" : "NY"},{"State" : "NJ"}];

var findLakes = function(state,callback){
  db.collection('lakes').find(state).toArray(callback);
}

async.map(states, findLakes , function(err, results){
    // do something with array of results
});
Run Code Online (Sandbox Code Playgroud)