如何在使用Nodejs调用回调函数之前等待N个查询完成

时间:2016-07-22 15:26:50

标签: javascript sql node.js postgresql promise

我正在尝试创建一个查询数据库并返回对象列表的函数,对于每个对象,我需要查询数据库并返回所有查询的结果。

如何等待所有查询完成,还是应该以同步方式执行?如果是这样如何?难道我不会利用这些事实,即它们都是选择查询并且不相互依赖,因此并行运行它们以优化时间吗?这是一个糟糕的设计吗?或者我应该使用存储过程吗?

getTopActiveUsers:function(callback) {
    pool.connect(function (err, client, done) {
        if (err)
            callback(null, err);
        else {
            User.finAll(client,function(users) {
                for(var i=0;i<users.length;i++) {
                    Application.findByUser(users[i].id,function(applications) {
                        // here i have the applications for user i
                    })
                }
                // need to call the callback function when all queries finishes
            })
        }
    });
}

2 个答案:

答案 0 :(得分:3)

async 库适合您。 parallel 方法并行执行所有请求,等待它们全部完成。

getTopActiveUsers : function(callback) {
pool.connect(function(err, client, done) {
    if (err) {
        callback(null, err);
    } else {
        User.finAll(client, function(users) {
            var requests = [];

            for (var i = 0; i < users.length; i++) {
                requests.push(function(asyncCallback) {
                    Application.findByUser(users[i].id, function(applications) {
                        // here i have the applications for user i
                        asyncCallback();
                    });
                });

            }

            async.parallel(requests, function(err) {
                // Requests are finished here
            });
        })
    }
});
}

文档: http://caolan.github.io/async/

答案 1 :(得分:1)

由于这些都可以并行运行,因此使用现有代码的最简单方法就是保留一个计数器:

getTopActiveUsers:function(callback) {
    pool.connect(function (err, client, done) {
        if (err)
            callback(null, err);
        else {
            User.findAll(client,function(users) {
                var doneCnt = 0;
                for(var i=0;i<users.length;i++) {
                    Application.findByUser(users[i].id,function(applications) {
                        // here i have the applications for user i
                        ++doneCnt;
                        if (doneCnt === users.length) {
                            callback(null, someResult);
                        }
                    })
                }
            })
        }
    });
}

更高级(也更灵活)的机制是学习和使用基于承诺的数据库接口,然后您可以使用Promise.all()跟踪多个异步操作的完成时间。