Reputation: 791
I have a function which contains another function call inside a for loop.
outerFunction(){
for (var j = 0; j < geoAddress.length; j++) {
innerFunction(j);
}
}
I need to wait till all the calls to innerFunction is complete. If I need parallel execution of these functions, how to achieve this in JavaScript?
Upvotes: 1
Views: 4264
Reputation: 9788
If you don't want to use external library for this you could make a scope object such as process
which keeps track of how many innerFunction
calls are still pending, and calls outer callback cb
when it is finished.
The point with this is that you still get the benefits of async execution, but you just make sure that your code won't execute the next part until all innerFunction belonging to outerFunction are actually finished:
outerFunction(function() {
console.log("All done for outerFunction! - What you should do next?");
// This block is executed when all innerFunction calls are finished.
});
JavaScript:
// Example addresses
var geoAddress = ["Some address X", "Some address Y"];
var innerFunction = function(geoAddress, process) {
// Your work to be done is here...
// Now we use only setTimeout to demonstrate async method
setTimeout(function() {
console.log("innerFunction processing address: " + geoAddress);
// Ok, we update the process
process.done();
}, 500);
};
var outerFunction = function(cb) {
// Process object for tracking state of innerFunction executions
var process = {
// Total number of work ahead (number of innerFunction calls required).
count: geoAddress.length,
// Method which is triggered when some call of innerFunction finishes
done: function() {
// Decrease work pool
this.count--;
// Check if we are done & trigger a callback
if(this.count === 0) {
setTimeout(cb, 0);
}
}
};
for (var j = 0; j < geoAddress.length; j++) {
innerFunction(geoAddress[j], process);
}
};
// Testing our program
outerFunction(function() {
console.log("All done for outerFunction! - What you should do next?");
// This block is executed when all innerFunction calls are finished.
});
Output:
innerFunction processing address: Some address X
innerFunction processing address: Some address Y
All done for outerFunction! - What you should do next?
Here is js fiddle example
Cheers.
Upvotes: 0
Reputation: 2599
Edit - Doing Things the Node Way Using Q Promise Library
If you're using the Q promise library, then try the following:
outerFunction(){
var promises = [];
for (var j = 0; j < geoAddress.length; j++) {
deferreds.push(innerFunction(j));
}
Q.all(promises).then(function(){
// do things after your inner functions run
});
}
Even if you're not using this particular library, the principle is the same. One should have one's function return a promise or have it wrapped in a promise as in the Q.denodify method, push all calls to an array of promises, pass said array to your library's equivalent of .when() (jQuery) or .all() (Q Promise Library) and then use .then() to do things after all promises are resolved.
Upvotes: 2
Reputation: 507
outerFunction() {
var done = 0;
function oneThreadDone() {
done++;
if (done === geoAddress.length) {
// do something when all done
}
}
for (var j = 0; j < geoAddress.length; j++) {
setTimeout(function() { innerFunction(j, oneThreadDone); }, 0);
}
}
and inside inner_function call oneThreadDone() function (reference passed throught param)
Upvotes: 0
Reputation: 2654
Check out the async library. https://www.npmjs.org/package/async
Check out the documentation on "whilst". It sounds like it does just what you need. whilst(test, fn, callback)
var count = 0;
async.whilst(
function () { return count < 5; },
function (callback) {
count++;
setTimeout(callback, 1000);
},
function (err) {
// 5 seconds have passed
}
);
Upvotes: 2