我正在尝试创建一个查询数据库并返回对象列表的函数,对于每个对象,我需要查询数据库并返回所有查询的结果。
如何等待所有查询完成,还是应该以同步方式执行?如果是这样如何?难道我不会利用这些事实,即它们都是选择查询并且不相互依赖,因此并行运行它们以优化时间吗?这是一个糟糕的设计吗?或者我应该使用存储过程吗?
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
})
}
});
}
答案 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
});
})
}
});
}
答案 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()
跟踪多个异步操作的完成时间。