Reputation: 61
in following code snippet,6 gets printed 5 times. Kindly explain this output behavior.
as for every i, i am calling settimeout function, so console.log should have that value of i. Code :
for(var i = 1;i <= 5;i++) {
setTimeout(function() {
console.log("i:" + i);
},i*1000);
}
O/P 6 6 6 6 6
O/P intended 1 2 3 4 5
Upvotes: 0
Views: 42
Reputation: 4876
Even a timeout 0 will yield the same result, To understand this you have to understand the concept of callback in terms of event loop. Ideally a callback is executed only when the stack is empty the js code execution is stack based I mean the execution context so when you here say a for loop it means 1st i is pushed into stack so now stack handles the variable and its increment value when it comes to callback (setTimeout) it stores is as an event loop.
the only way the to run the block inside event-loop is when your stack is empty i.e when your loop ends as as its an closure function it retains the last value where all logs are printed.
See the example you will see 1 to 6 outer to callback as it gets executed in stack but callbacks only when your stack is empty.
If you want to best understand the execution context then go to loupe and copy paste your js code to see the action.
for(var i = 1;i <= 5;i++)
{
console.log(i)
setTimeout(function(){
console.log("i:" + i);
},0
);
}
Upvotes: 2
Reputation: 2555
that's because the function uses the variables in the same scope of the for loop
by the time the setTimeout function is executed, the variable i in the scope has changed value, so all timers will print the last value of the loop
try passing the i value as an argument of setTimeout, so that it's evaluated immediately and the function can use a value in it's own scope, with no side effects playing tricks
for(var i = 1;i <= 5;i++)
{
setTimeout(function(a){
console.log("i:" + a);
},i*1000,i
);
}
Upvotes: 1
Reputation: 956
Since setTimeout is asynchronous , the for loop would have run before the sitetimeOut function is called . The last iteration of the for loop loop sets i to 6 . Hence once the set timeOut function runs after the for loop it will print out 6 .
Upvotes: 0
Reputation: 544
In js, variables have block/function scope and also setTimeout work asynchronously.
Upvotes: 0