KingKongFrog
KingKongFrog

Reputation: 14419

Javascript closure setTimeout interval issue

Why is the following logged every 1 second? I'm multiplying 1000 milliseconds to the increment. Shouldn't my logs show up after 1 second, then 2 seconds, then 3 seconds?

for (var i = 0; i < 5; i++) {
  (function(r) {
    setTimeout(
      function() { 
        console.log(r)
      } 
    , r * 1000 );
  })(i)
}

JSFIDDLE

Upvotes: 2

Views: 126

Answers (4)

user3276552
user3276552

Reputation: 1072

it's working correctly, basically, the loop serves as shorthand for writing this:

setTimeout( function(){ console.log(0) }, 1000)
setTimeout( function(){ console.log(1) }, 2000)
setTimeout( function(){ console.log(2) }, 3000)
setTimeout( function(){ console.log(3) }, 4000)
setTimeout( function(){ console.log(4) }, 5000)

so it would make sense that each goes off one after the other kinda looking like this:

▀
▀▀
▀▀▀
▀▀▀▀
▀▀▀▀▀

what you might be looking for is

(function newTimeout( seconds ){
  if( seconds > 4 ) return;
  console.log(seconds);
  setTimeout( function(){
    newTimeout( seconds + 1 )
  }, seconds * 1000);
})(0);

which would kinda look like this

▀
 ▀▀
   ▀▀▀
      ▀▀▀▀
          ▀▀▀▀▀

hope it helps!

Upvotes: 4

Allan Chua
Allan Chua

Reputation: 10175

There is actually nothing wrong with your loop brother. What happens is that the setTimeout executions executed simultaneously. Remember your small loop execution time is just a matter of milliseconds.

Proof of concept.

        for (var i = 0; i < 5; i++) {
            console.log(new Date() + " Loop Executed: " + (i + 1));
            (function (r) {
                setTimeout(
                  function () {
                      console.log(new Date() + " " + r)
                  }
                , (r * 1000));
            })(i)
        }

Upvotes: 3

Spencer Wieczorek
Spencer Wieczorek

Reputation: 21565

That's because calling setTimeout will not stop the executing of code. The loop will continue and do all the setTimeout() in each loop from the start. That's why it logs every second. They do go off after 1, 2, 3, and 4 seconds, but start all at the same time.

Upvotes: 2

Jaromanda X
Jaromanda X

Reputation: 1

Why is the following logged every 1 second?

because the first one is logged after 0 x 1000ms, the second one after 1 x 1000ms, third one after 2 x 1000ms ... so, after 0, 1, 2, 3, 4 seconds

Shouldn't my logs show up after 1 second, then 2 seconds, then 3 seconds?

actually after 0, 1, 2, 3 and 4 seconds - but it's not cumulative, you're starting ALL the timeouts at virtually the same time

Upvotes: 2

Related Questions