lundi 30 mars 2015

How to handle callbacks in a for loop(Node.JS)

I am trying to write a code with NodeJS where I grab data from an external API and then populate them in MongoDB using Mongoose. In between that, I'll check to see if that particular already exists in Mongo or not. Below is my code.



router.route('/report') // the REST api address
.post(function(req, res) // calling a POST
{
console.log('calling report API');
var object = "report/" + reportID; // related to the API
var parameters = '&limit=100' // related to the API
var url = link + object + apiKey + parameters; // related to the API

var data = "";
https.get(url, function callback(response)
{
response.setEncoding("utf8");
response.on("data", function(chunk)
{
data += chunk.toString() + "";
});

response.on("end", function()
{
var jsonData = JSON.parse(data);
var array = jsonData['results']; // data is return in array of objects. accessing only a particular array
var length = array.length;
console.log(length);

for (var i = 0; i < length; i++)
{
var report = new Report(array.pop()); // Report is the schema model defined.
console.log('^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^');
console.log(i);
console.log('*****************************');
console.log(report);
console.log('*****************************');
// console.log(report['id']);

/*report.save(function(err)
{
if(err)
res.send(err);
});*/

Report.find({id:report['id']}).count(function(err, count) // checks if the id of that specific data already exists in Mongo
{
console.log(count);
console.log('*****************************');
if (count == 0) // if the count = 0, meaning not exist, then only save
{
report.save(function(err)
{
console.log('saved');
if(err)
res.send(err);
});
}
});
};
res.json({
message: 'Grabbed Report'
});
});
response.on("error", console.error);
});
})


My problem is that since NodeJS callbacks are parallel, it is not getting called sequentially. My end result would be something like this :



  1. Calling report API

  2. console.log(length) = 100

  3. ^^^^^^^^^^^^^^^^^^^^^^^^

  4. console.log(i) = starts with 0

  5. *******************************

  6. console.log(report) = the data which will be stored inside Mongo

  7. *******************************

  8. number 3 - 7 repeats 100 times as the length is equals to 100

  9. console.log(count) = either 0 or 1

  10. number 9 repeats 100 times

  11. console.log('saved')

  12. number 11 repeats 100 times

  13. Lastly, only the last out of 100 data is stored into Mongo


What I need is some sort of technique or method to handle these callbacks which are executing one after the other and not sequentially following the loop. I am pretty sure this is the problem as my other REST APIs are all working.


I have looked into async methods, promises, recursive functions and a couple others non which I could really understand how to solve this problem. I really hope someone can shed some light into this matter.


Feel free also to correct me if I did any mistakes in the way I'm asking the question. This is my first question posted in StackOverflow.


Aucun commentaire:

Enregistrer un commentaire