I am using node.js
I have a function with several parameters I need to call inside a loop. The function must be called with the loop iterator as a parameter and the loop must not call the function again until it is finished processing.
Something like this (sync method): (note that someFunc is an asynchronous function)
var totCount = 1000;
for (var x = 0 ; x < totCount ; x++) {
someFunc(x, parm2, parm3, parm4);
}
I understand that in node, someFunc could execute in any order but for this case, it absolutely must execute with x = 0 then 1 then 2 etc.
It seems that the async library call "async.whilst" will do this but I am having trouble translating the example into my real life code.
Here is the example for "async.whilst":
var count = 0;
async.whilst(
function () { return count < 5; },
function (callback) {
count++;
setTimeout(callback, 1000);
},
function (err) {
// 5 seconds have passed
}
);
Note that since I potentially have to call the function someFunc many times, normal callback approach will not work.
How do I translate this into my code? (I am assuming "async.whilst" is the correct approach. If not please specify correct approach)
Sounds like you want to use promises, assuming you can set someFunc up so it returns a promise. You could do something like this:
var promise=new Promise().fulfill();
var totCount = 1000;
for (var x = 0 ; x < totCount ; x++) {
promise=promise.then(function(){return someFunc(x, parm2, parm3, parm4);});
}
promise.then(function(){console.log("done");});
The exact syntax will depend on the promises library you choose to use.
The following example will work assuming that someFunc is async and takes a callback as the last argument. Whether or not it does depends on how it's implemented. If it's part of another library it probably does.
var count = 0;
var totCount = 1000;
async.whilst(
function () { return count < totCount; },
function (callback) {
someFunc(count, parm2, parm3, parm4, callback);
count++;
},
function (err) {
// someFunc has been called totCount times, or an error has occured
}
);
In case someFunc is not async but you want to run the loop asynchronously to avoid blocking, you would simply call the callback after the function call.
//...
function (callback) {
someFunc(x, parm2, parm3, parm4);
count++;
callback();
},
// ...
Update
Doing it without async/promises (not tested):
var count = 0;
var totCount = 1000;
function loop () {
// Async lets you provide you own check-method
if(count >= totCount) {
// Async lets you provide your own done-method
return done();
}
// Async does setImmediate/process.nextTick somewhere around here
myFunc(count, param, param, function() {
// Async checks for errors here
count++;
loop();
});
}
function done () {
// Async provides any errors here
console.log("done");
}
I commented where async does some extra stuff that's probably good to have (most approximately, check out the source code for specifics, it's surprisingly easy to read). For example if someFunc is not actually asynchronous but just calls a callback, this will kill the event loop just as much as using for(...).