Understanding Closures
Solution 1:
In the first code block, the for
loop will run to completion. Each time through the loop will schedule a setTimeout()
call for some time in the future. But, when that setTimeout()
actually fires, the value of i
will be the value at the END of the for
loop for all the setTimeout()
calls.
In the second code block, the for
loop will again run to completion, but each time through the for
loop it creates a new function closure that "captures" the value if i
separately for each timer callback and thus it will display the desired value of i
inside the setTimeout()
callback because it has been saved separately for each timer.
You can think of your second code more like this:
functionmyTimer(index) {
setTimeout(function () {
console.log('i value in closure is ' + index);
}, index);
}
for (var i = 0; i <= 2000; i += 1000) {
myTimer(i);
}
The only difference between your second code block and this expanded code here is that your second code block uses an anonmymous IIFE instead of the named myTimer()
function shown here, but the execution is the same. The use of this function inside the for
loop creates a Javascript function closure that saves the value of i
so that when the setTimeout()
calls its callback later, that unique value of i
is available to the callback and it does this for each invocation of that function.
The construction:
(function (i) {
some async operation here that uses i
})(i);
is called an immediately invoked function expression (abbreviated IIFE) and is a quick way to create a closure in Javascript.
See this prior answer for more info on the topic: Asynchronous Process inside a javascript for loop
Post a Comment for "Understanding Closures"