2014-09-02 166 views
1

我是新來的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); 
+0

'c_db.count({ 'SHIPDATE':{ '$ GTE':新的日期(firstDay), '$ LTE':新的日期(LASTDAY)} },函數(錯誤,查詢){'爲什麼你要做'新日期(firstDay)'?那些不是日期對象? – royhowie 2014-09-02 17:54:00

+0

firstDay和lastDay被硬編碼在開頭,thx提及:) – fluidsnake 2014-09-02 18:11:52

+0

我想你可以定義一個回調函數'whenFinished',當'test_json.length === i - 1'時被調用。由於關閉,如果你在'test_json.push(item)'之後放置它,它會調用它,即使for循環已經完成循環。所以''test_json.push'後面的'if(condition)whenFinished()'應該可以工作。 – royhowie 2014-09-02 22:42:33

回答

1

當您使用異步回調編寫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); 
});