Consider such loop:
for(var it = 0; it < 2; it++)
{
setTimeout(function() {
alert(it);
}, 1);
}
The output is:
=> 2
=> 2
I would like it to be: 0, 1. I see two ways to fix it:
Solution # 1.
This one based on the fact that we can pass data to setTimeout.
for(var it = 0; it < 2; it++)
{
setTimeout(function(data) {
alert(data);
}, 1, it);
}
Solution # 2.
function foo(data)
{
setTimeout(function() {
alert(data);
}, 1);
}
for(var it = 0; it < 2; it++)
{
foo(it);
}
Are there any other alternatives?
Not really anything more than the two ways that you have proposed, but here's another
Essentially, you need to capture the variable value in a closure. This method uses an immediately invoked anonymous function to capture the outer variable value
it
in a local variablem
.Here's a Working Demo to play with. add /edit to the URL to see the code
Similar to the other solutions, but in my opinion cleaner:
This keeps the same variable name for the capture, and does it for the entire loop, separating that from the logic of the timeout setup. If you want to add more logic inside the block, you can trivially do that.
The only thing I don't like about the solution is the repeat of "it" at the end.
Similar to above solution but self invoking inside of setTimeout function
With the let keyword you can get around this completely: