处理与nodejs异步回调循环
问题描述:
我是新来的nodejs和猫鼬。 我有一个从2009年到现在的数据库,并希望统计每个月的数据数量, 并返回为json数组。缓慢的异步回调会导致所有日期为2014年8月1日处理与nodejs异步回调循环
实现此目的的正确方法是什么?
var dbURL = 'mongodb://localhost/database';
var db = require('mongoose').connect(dbURL);
var c_db = require('./models/models.js').c_db;
var start_date = new Date(2009,0,1);
end_date = new Date(2014,8,1),
next_date = new Date();
var test_json=[];
var total_months = (end_date.getFullYear() - start_date.getFullYear())*12 + (end_date.getMonth() - start_date.getMonth());
var next_date = start_date;
for(var i=0;i<total_months;i++){
var firstDay = new Date(next_date.getFullYear(), next_date.getMonth(), 1);
var lastDay = new Date(next_date.getFullYear(), next_date.getMonth() + 1, 0);
next_date.setDate(lastDay.getDate()+1);
c_db.count({'shipdate':{'$gte':new Date(firstDay),'$lte':new Date(lastDay)}},function(err,query){
var item = {
"Date": firstDay,
"Count": query
}
test_json.push(item);
});
}
setTimeout(function(){
console.log(test_json);
},5000);
答
当您使用异步回调编写javascript时要小心。你想要做的是在当前异步完成时继续循环中的下一个项目。您可以使用的 “异步” 模块:https://github.com/caolan/async
var async = require("async");
var dbURL = 'mongodb://localhost/database';
var db = require('mongoose').connect(dbURL);
var c_db = require('./models/models.js').c_db;
var start_date = new Date(2009,0,1);
end_date = new Date(2014,8,1),
next_date = new Date();
var test_json=[];
var total_months = (end_date.getFullYear() - start_date.getFullYear())*12 + (end_date.getMonth() - start_date.getMonth());
var next_date = start_date;
async.timesSeries(total_months, function(n, next) {
var firstDay = new Date(next_date.getFullYear(), next_date.getMonth(), 1);
var lastDay = new Date(next_date.getFullYear(), next_date.getMonth() + 1, 0);
next_date.setDate(lastDay.getDate()+1);
c_db.count({'shipdate':{'$gte':new Date(firstDay),'$lte':new Date(lastDay)}},function(err,query){
var item = {
"Date": firstDay,
"Count": query
}
test_json.push(item);
next();
});
}, function(e) {
console.log(test_json);
});
'c_db.count({ 'SHIPDATE':{ '$ GTE':新的日期(firstDay), '$ LTE':新的日期(LASTDAY)} },函数(错误,查询){'为什么你要做'新日期(firstDay)'?那些不是日期对象? – royhowie 2014-09-02 17:54:00
firstDay和lastDay被硬编码在开头,thx提及:) – fluidsnake 2014-09-02 18:11:52
我想你可以定义一个回调函数'whenFinished',当'test_json.length === i - 1'时被调用。由于关闭,如果你在'test_json.push(item)'之后放置它,它会调用它,即使for循环已经完成循环。所以''test_json.push'后面的'if(condition)whenFinished()'应该可以工作。 – royhowie 2014-09-02 22:42:33