fluidsnake
fluidsnake

Reputation: 11

Handling loop with nodejs asynchronous callback

I'm new to nodejs and mongoose. I have a database dated from 2009 until now and would like to count number of data of each month, and return as json array. Slow async callback results all dates as Aug. 1, 2014

What is the proper way to implement this?

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);

Upvotes: 1

Views: 72

Answers (1)

Comtaler
Comtaler

Reputation: 1630

Be careful when you are writing javascript with async callbacks. What you want to do is to continue to the next item in the loop when the current async is finished. You can use a the "async" module: 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);
});

Upvotes: 1

Related Questions