Possible Duplicate:
Javascript closure inside loops - simple practical example
Seen many posts talking about setTimeout
and closures but I'm still not able to pass in a simple for loop counter.
for (i = 0; i < 5; i++) {
setTimeout(function () {
console.log(i);
}, Math.floor(Math.random() * 1000));
}
Gives
5
5
5
5
5
Would like to have
0
1
2
3
4
What's wrong ?
Please don't flame, I thought I have understood the setTimeout()
tale but apparently not.
The setTimeout function callback isn't triggered until the for loop execution has completed. When the for loop has finished executing the value of i is 7. Now when the setTimeout call begins to execute it uses the last set value of i which is 7. Hence 7 is printed in all the setTimeout callbacks.
Notes. The setTimeout() is executed only once. If you need repeated executions, use setInterval() instead. Use the clearTimeout() method to prevent the function from starting.
To create pause or delay in a JavaScript for loop, we should use await with a for-of loop. to define the wait function that returns a promise that calls setTimeout with resolve to resolve the promise in ms milliseconds. Then we define the loop function that runs a for-of loop to loop through an array.
setTimeout() The global setTimeout() method sets a timer which executes a function or specified piece of code once the timer expires.
You can use a closure to keep a reference to the current value of i
within the loop:
for (i = 0; i < 5; i++) {
(function(i) {
setTimeout(function () {
console.log(i);
}, Math.floor(Math.random() * 1000));
})(i); //Pass current value into self-executing anonymous function
}
However, this is unlikely to print the numbers in order since you use a random timeout (you could use i * 1000
instead to make the numbers print in ascending order, one second apart).
Here's a working example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With