【发布时间】:2015-05-28 07:44:33
【问题描述】:
我正在进行多个异步数据库查询,并尝试将所有这些数据存储在一个大列表中,当所有查询完成后,我想将此数据作为响应发送。
我面临两个问题,
如何判断异步调用结束
如何将变量传递给异步函数,以便将其结果存储在此变量中,以便我以后使用
功能说明
我有一个应用程序,它在后台每 k 分钟执行一次,并且在每次执行时,任务信息都保存在 mongodb 数据库中。我在完成时遇到问题的函数称为 fetchHistoryStatistics。该函数应该获取每天执行的执行次数。
算法:
- 获取所有不同的执行日期(年-月-日)
- 获取所有正在执行的不同帐户
- 为每个用户获取每天的执行次数
代码:
function fetchHistoryStatistics(response){
var dates = [], timeline = {}, query;
//Distinct Dates
db.collection('master')
.distinct("date", function(err, ds){
for(var i in ds){
var d = ds[i].getFullYear() + " " + (ds[i].getMonth()+1) + " " + ds[i].getDate();
if (dates.indexOf(d)==-1){
dates.push(d);
}
}
//Distinct Users
db.collection('master')
.distinct("screen_id", function(err, users){
//Fetching History Data
for(var i in users){
timeline[users[i]]={};
for (var j in dates){
timeline[users[i]][dates[j]] = {};
if(dates[parseInt(j)+1] != undefined){
query = {"screen_id": {"$eq": users[i]}
, "date": {"$gte": new Date(dates[j]), "$lt": new Date(dates[parseInt(j)+1])
}};
db.collection('master')
.find(query)
.toArray(function(err, results){
// **!! TODO !!**
// The problem is occuring here, when i try to store the data in the variable timeline
timeline[users[i]][dates[j]] = results.length;
console.log("-----------------", users[i], dates[j]);
//console.log(query);
//console.log(results);
console.log("timeline :", timeline);
})
;
}else{
query = {"screen_id": {"$eq": users[i]}
, "date": {"$gte": new Date(dates[j])
}};
db.collection('master')
.find(query)
.toArray(function(err, results){
timeline[users[i]][dates[j]] = results.length;
console.log("-----------------", users[i], dates[j]);
//console.log(query);
//console.log(results);
console.log("timeline :", timeline);
})
;
}
}
}
console.log("timeline :", timeline);
})
;
})
;
// !! TODO !!
// And another problem here
// Because the functions are Asynchronous i need to be able to wait for all the executions to have terminated,
// such that i can send all the collected data back in the response
response.send({});
}
【问题讨论】:
-
查看这个答案,我认为 Promise 会让这更容易使用:stackoverflow.com/a/23771854/693275
-
当您运行 FOR 循环时,您会失去异步性
,因为它们都无需等待即可执行。您是否尝试过使用 Caolan 的 asyn 库来迭代这些数组?类似 async.eachSeries(dates, function(d, callback) { // 处理 d,然后回调执行下一个数组项 }));
标签: javascript node.js mongodb asynchronous