Asynchronous closure call in loop in Javascript

Date: 2013-05-15

Problem: Async closure call in loop may cause mistake, Consider following code

for(var i = 0; i<4; i++){
    setTimeout(function(){
        console.log(i);
    },1000)
}

what will the output be? 0 1 2 3? no, actually it will be 4 4 4 4

The reason is Async, when the closure: function(){console.log(i)} been called, the loop already finished, and the i is been changed to 4, so when the closure been called, all the i is 4

How to solve this problem

we need to avoid the change of the i in the closure, this time, we need use another closure:

for(var i = 0; i<4; i++){
    (function(i){
        setTimeout(function(){
            console.log(i);
        },1000)
    })(i)
}

we make a closure and call it instantly in the loop, so when the closure is been called each time, the i is different, so in the closure inside this closure, the i is different.

Async and Closure are both great features of Javascript, when using them in a correct way, they are very powerful and flexiable. And when you are using them together, you must be careful.

Reference: Closures