I'm having a little bit of an issue with some asynchronus looping with calls to mongodb. I have tried several approaches and looked into libraries such as async and co-monk. (I'm using monk as my connection etc).
I have an array of data that I need to pass through to a mongo collection to check its ok etc..My background is PHP/Sql, so the async nature of mongo is a little hard to get my head around.
Some basic sudo code of what I'm trying to do:
function check (collection) {
var records = { { body: "Test 1"}, { body: "Test 2" } };
for (var i in records) {
collection.find({ body: records[i].body }, {}, function (e, rows) {
console.log(rows);
});
}
}
It only executes on the final loop of the records. I know this is due to the async nature of JS, but how do I structure it properly to work like this?
Thanks,
The general key to asynchronous processing is that you want to have some indication of when the current iteration is done before moving on to the next iteration. Since the actual operations such as
.find()
here themselves employ a "callback" which is "called" when the operation is completed with a response, then what you usually want to do is call something that signifies your end of iteration in the same section of code.In a basic way, you can get a similar result as you can in traditional loops with the "async.eachSeries" method, which will only let "one iteration at a time" take place:
So each of the array arguments are passed in to the "iterator" function here as a "item" parameter, and a second argument is a "callback" function to be used later. Every time the iterator is called, that argument is passed to the
.find()
method which in turn has a "callback" of its own, where the "error" or "documents" response is given.Inside that callback, the "callback" provided by the "iterator" function is then called to signal the completion of that current iteration. This allows the "each" function here to continue and indeed call the next "iteration" and process the next array element.
Noting your background, be aware of the correct way to notate an "array" in JavaScript with the
[]
brackets as shown. This is generally an important difference when working with arrays.There are other variations of "async.each" and "async.eachLimit" which both allow some degree of parallel processing, but the "Series" method does things "in order" in a way that you are used to with traditional loops.
So where loop operations are "non-blocking", you need to signify when that loop completes before you want to move on.