Possible Duplicate:
javascript: execute a bunch of asynchronous method with one callback
I've been struggling with this issue for days now, but I just can't figure out an elegant way to handle it. Here's the problem.
I'm running a forEach loop, and I need to know when everything has been completed. Since forEach loops are blocking, it should be easy enough to just drop a console.log
after the forEach loop, which will run when the forEach loop is complete. However, if there is any function inside of the forEach loop that's not sync, this entire system breaks down very quickly, and I have no way of knowing when the contents of the loop are complete other than very strange hacky counters and if statements. My question is whether there is an elegant way to handle this situation in javascript.
Here are a couple examples:
In this case, the forEach loop works perfectly nicely, since everything in the loop is sync.
[1,2,3].forEach(function(num){
console.log("we're on " + num);
});
console.log('done counting!')
//=> we're on 1
//=> we're on 2
//=> we're on 3
//=> done counting!
This is where we start running into problems though, as a basic example:
[1,2,3].forEach(function(num){
setTimeout(function(){ console.log(num) }, 200);
});
console.log('done counting!');
//=> done counting!
//=> we're on 1
//=> we're on 2
//=> we're on 3
Although it does make sense that this is happening, I now have the unfortunate issue on my hands that I need a callback for when we are done counting, and there's no smooth way for me to have one other than something gross like this:
var counter = 0;
var numbers = [1,2,3]
var log_number = function(num){
console.log("we're on " + num);
counter++;
if (counter == numbers.length) {
console.log("done counting!")
}
}
numbers.forEach(function(num){
setTimeout(log_number(num), 200);
});
//=> we're on 1
//=> we're on 2
//=> we're on 3
//=> done counting!
Goodness, that's an awful lot of overhead. Is there any smoother way to make this happen? I've checked out promises, deferred's, and sequences, but I haven't really been able to implement any one of them in a way that makes this more concise : (
To be clear, it's not setTimeout specifically that is my issue, it generally having async functions running inside a sync function - that was just the simplest example.