2

I'm trying to log numbers to the console on specific intervals. However, what occurs instead is that it waits the set interval, then logs everything out as normal.

I've tried two different ways to create a closure both work. But do nothing in regards to the delayed console.log.

function timeOutLoop(x){
   for(var i = 0; i<=x; i++){
    (function(n){
      setTimeout(function(){console.log(n)},5000)
    })(i)

     setTimeout(function(num){
      return function(){
        console.log(num)
      }
    }(i),1000)
  }
}

timeOutLoop(33)

I was under the impression that each setTimeout will go on the event queue with the context provided by the closure. What gives?

Nick Lee
  • 842
  • 2
  • 11
  • 27
  • 1
    You're giving each timer exactly the same wait time. (well 2 different wait times, but still.) – Pointy Feb 14 '19 at 20:07
  • 1
    To be clear: the outer `for` loop will finish up basically immediately; setting up each timer will take microseconds. They will then all wait either 1 or 5 seconds and all go off at the same time. It's like lighting the fuses of 33 firecrackers all at exactly the same time. – Pointy Feb 14 '19 at 20:10
  • Thank you. How should I proceed? Do you want an official answer or should I answer it myself? – Nick Lee Feb 14 '19 at 20:10
  • Well what is it that you want to do? One possibility is to multiply your timer constant (1000 or 5000) by the iteration value, to give each timer its own delay. – Pointy Feb 14 '19 at 20:12

3 Answers3

2

Since the loop basically executed instantly, with the first one there will not be much of a difference since the time is in milliseconds and as for the second one, they will all execute after 1 second.

Using a combination of the two methods, you can achieve it:

 function timeOutLoop(x) {
  for(var i = 0; i <= x; i++) {
    setTimeout(function(num) {
      return function(){
          console.log(num);
      }
    }(i), i * 1000);
  }
}

timeOutLoop(33)
Calvin Nunes
  • 6,376
  • 4
  • 20
  • 48
Omari Celestine
  • 1,405
  • 1
  • 11
  • 21
2

setTimeouts start at the same time so if you want to start a timeout after another you can create a recursive function :

function timeOutLoop(x, i=0){
   if(i<=x){
      console.log(i);
      i++;
      setTimeout(function(){timeOutLoop(x, i)},1000);
   }
}
timeOutLoop(33)

You can set timeout value to whatever you like.

r3zaxd1
  • 697
  • 9
  • 17
1

function timeOutLoop(x){
    for(let i = 0; i<=x; i++){
        setTimeout(function(){console.log(i)},i * 1000);    
    }
}
timeOutLoop(33);

Is this what you are looking for? Change from var to let in order to keep the variable i intact inside the loop scope. More here about let vs var.

Also multiply i by 1000 to print every second until reaching 33.

Lolpez
  • 849
  • 8
  • 17