If findOne
completes asynchronously, and it certainly looks like it does, then that forEach
will block for maybe a fraction of a millisecond. Later, findOne
will call each of the callbacks, when each of its lookups completes. From a blocking perspective, that code is fine, given the proviso that findOne
completes asynchronously.
But, the code has a different issue: You're assuming the callbacks will happen in order, by doing this:
if (index === array.length - 1) {
completeSend(suggesterResults);
}
You can't make that assumption unless findOne
documents it (I looked on the sails.js site; couldn't find any documentation for findOne
other than an entry in a bullet list that didn't say anything). The callbacks could arrive out-of-sequence, for instance if one lookup is faster than one before it.
Instead, you'll want to track how many callbacks you've gotten, and call completeSend
when you've gotten the same number as the requests you've made, rather than relying on the index.
If suggesterResults
is blank when you start and nothing is going to modify suggestions
while the calls are outstanding, you can use its length
:
suggestions.forEach(function (element, index, array){
Suggester.findOne({
"id": element.suggester_id
},function(err,docs){
suggesterResults.push(docs);
console.log("I am adding to array: " + docs);
if (suggesterResults.length === array.length) {
completeSend(suggesterResults);
}
});
})
But if either of those caveats isn't true, you're better off with a counter:
var waitingon = 0;
suggestions.forEach(function (element, index, array){
++waitingon;
Suggester.findOne({
"id": element.suggester_id
},function(err,docs){
suggesterResults.push(docs);
console.log("I am adding to array: " + docs);
if (--waitingon === 0) {
completeSend(suggesterResults);
}
});
})
That looks like a race condition, but it isn't because this is a single-threaded environment. All of the forEach
callbacks will happen before the first findOne
callback does, so waitingon
will rise to the appropriate level before we start decrementing it. (This also allows for the possibilty, which seems unlikely, that suggestions
is sparse.)