So I'm writing a function that makes a bunch of database calls. I want to store their results in an array and trigger a callback once they're all done.
Some pseudocode may help:
function getStuff (array, callback) {
var results = [];
var done = 0;
for (var i = 0, len = array.length; i < len; i++) {
database.fetchOne(array[i], function(result) {
results[i] = result;
done++;
if (done == len)
callback(results);
});
}
}
This works great. However, I'm told it's bad practice to nest a closure inside a loop because it keeps defining the function every iteration, and that comes at a performance cost.
Other answers suggest moving the callback outside of the loop:
function getStuff (array, callback) {
var results = [];
var done = 0;
for (var i = 0, len = array.length; i < len; i++) {
database.fetchOne(array[i], myCallback.bind(this, i, results, done, callback));
}
}
function myCallback (i, results, done, callback, result) {
results[i] = result;
done++;
if (done == len)
callback(results);
}
But this doesn't work since done
has an immutable type, so it doesn't change the value of done
in getStuff
.
So... what do I do?