Aman
Aman

Reputation: 671

Node async array loop result not as expected

function asyncForEach(array,cb) {
    array.forEach(function(i){
        setTimeout(cb(i),0);
    });
}
asyncForEach([1,2,3,4], function(i) {
    console.log(i);
});

console.log("After loop");

The result of the above snippet as you would see is

1
2
3
4
After loop

What I expected was

After loop
1
2
3
4

What I thought would happen is that function asyncForEach would be added to the call stack, and for each element in array, callback in setTimeout would be pushed to callback queue. Console.log("After loop"); would be printed and call stack would then get empty, following which all the callbacks would execute one by one. But that doesn't seem to be the case. Can anyone explain ?

Thanks.

Upvotes: 1

Views: 42

Answers (2)

Ankush G
Ankush G

Reputation: 1081

To get the expected output you need following change:

function asyncForEach(array,cb) {
    array.forEach(function(i){
        setTimeout(function(){cb(i)},0); // CHANGE IS HERE
    });
}
asyncForEach([1,2,3,4], function(i) {
    console.log(i);
});
console.log("After loop");

Basically when u provide a function call(without parenthesis) inside the setTimeout function, you are actually calling that function right away. To schedule the function call after given timeout you have to provide the function inside that setTimeout method like I provide in my example above.

Upvotes: 0

nem035
nem035

Reputation: 35491

The problem is that you're manually calling the callbacks in the forEach and passing result of this into setTimeout.

setTimeout(cb(i), 0); // <-- you call cb(i) and pass its result into setTimeout

What you wanted to do was something like:

setTimeout(cb, 0, i);

Or more explicitly:

setTimeout(function() {
  cb(i);
}, 0);

Full example:

function asyncForEach(array,cb) {
    array.forEach(function(i){
        setTimeout(cb, 0, i);
    });
}
asyncForEach([1,2,3,4], function(i) {
    console.log(i);
});

console.log("After loop");

Upvotes: 2

Related Questions