Written by James McDonald

February 4, 2019

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

Submit a Comment

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

The reCAPTCHA verification period has expired. Please reload the page.

You May Also Like…

Squarespace Image Export

To gain continued access to your Squarespace website images after cancelling your subscription you have several...

MySQL 8.x GRANT ALL STATEMENT

-- CREATE CREATE USER 'tgnrestoreuser'@'localhost' IDENTIFIED BY 'AppleSauceLoveBird2024'; GRANT ALL PRIVILEGES ON...

Exetel Opt-Out of CGNAT

If your port forwards and inbound and/or outbound site-to-site VPN's have failed when switching to Exetel due to their...