Why does all the output of a for loop appear at once when using setTimeout?
for(var i = 0; i < 5; i++){
(function(i){
setTimeout(function(){
console.log('value is ', i);
}, 3000);
})(i);
}
When you run the above code after 3 seconds the output of all iterations of the loop appear:
value is 0
value is 1
value is 2
value is 3
value is 4
This is because the for loop runs and setTimeout sets each execution for 3 seconds in the future. But because the loop completes in a fraction of a second the output appears all at once
setTimeout needs to be set progressively into the future
for(var i = 0; i < 5; i++){
(function(i){
setTimeout(function(){
console.log('value is ', i);
console.log('timeout is ' + 3000 * (i + 1))
}, 3000 * (i + 1));
})(i);
}
When you run the next block of code above you get the output appearing every 3 seconds
value is 0
timeout is 3000
value is 1
timeout is 6000
value is 2
timeout is 9000
value is 3
timeout is 12000
value is 4
timeout is 15000
The second for loop gives the desired results console.log appears 3 seconds, 6 seconds, 9 seconds etc ... from when the loop ran
So although this is logical. The behaviour can catch you out if you assume that each time setTimeout is called it adds to the time that was set with a previous call to setTimeout. In short setTimeout doesn't stack or add times together. From the moment the setTimeout function is called it runs the callback after the elapsed time has expired or as quick as the event loop can run them if there are previous task waiting in the event loop.
setTimeout called 5 times with a 3 second timeout in a loop will all execute at roughly the same time like thus:
===>
===>
===>
===>
===>
It doesn't do this:
===>
===>
===>
===>
===>
To get a stepped execution you have to lengthen the setTimeouts value and the number of milliseconds gap times the index of the loop plus 1 works well ( e.g 3000 * (i + 1)
)
===>
=======>
===========>
===============>
===================>
0 Comments