0

I am trying to figure out how to time this for statement so it happens every second or so. What ends up happening is that the x prints 5 for all logs because the for loop is looping before the Timeout happens. How can I time the loops so every iteration happens after the setTimeout finishes.

for (x = 0; x < 5; x++) {  
  var wait = setTimeout( function() { 
    console.log(x,"x"); 
  }, 800);
}
Paul Roub
  • 36,322
  • 27
  • 84
  • 93
Kostis
  • 119
  • 1
  • 12

3 Answers3

1

Use let x = 0 to make sure x is block scoped in the loop and multiply delay times index in order to increment each delay time

for (let x = 0; x < 5; x++) {
  setTimeout(function() {
    console.log(x, " x")
  }, (x + 1) * 800);
}
charlietfl
  • 170,828
  • 13
  • 121
  • 150
  • I think this helped me the most. charlietfl is there a specific reason for multiplying the 'x' with the time? – Kostis Dec 08 '17 at 17:18
  • the loop will complete in milliseconds... I assumed you wanted to increment each delay so they don't all run simultaneously – charlietfl Dec 08 '17 at 17:19
  • Important reading [JavaScript closure inside loops – simple practical example](https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – charlietfl Dec 08 '17 at 17:21
1

Other answers here are of course correct.

But going forward into the future async code is much easier using async / await.

So below is a simple example,.. It initially looks longer, due to utility function delay, but as your program gets larger using async / await will make your code much easier to follow.

Another advantage here too, is only 1 setTimeout is created,. So potentially more resource friendly. You could also achieve using 1 setTimeout without async / await but would require chaining the setTimeout's making the code even harder to follow.

// utility function do delay, 
// can be used again..
function delay(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}

//await can only be called from async function.
//so lets just create run function to get things started.

async function run () {
  for (let x = 0; x < 5; x++) {  
    await delay(800);
    console.log(x,"x"); 
  }
}

//lets get things started..
run ();
Keith
  • 22,005
  • 2
  • 27
  • 44
0

I think this is what you're trying to do:

for (x = 0; x < 5; x++) {  
  (function(n){setTimeout(()=>{console.log(n,"x");},800*n);})(x);
}
Eli Richardson
  • 934
  • 7
  • 25