1

for (let i = 10; i >= 0; i--) {
    setTimeout(function() {
        console.log(i);
    }, 1000);
}

I want to show a simple countdown from 10 to 0 with a 1 second delay between each subtraction. I use the above example and it shows all the numbers in an instant. How could I fix this?

darkchampionz
  • 1,174
  • 5
  • 24
  • 47
  • 1
    You are creating 10 timeouts all set at 1000. setTimeout is async, it does not wait until it finishes. It creates it and moves on. If you want it to be a delay you need to change the timeout delay time to match the delay you need it to wait for. – epascarello Mar 06 '23 at 16:53
  • 1
    You are reinventing setInterval – epascarello Mar 06 '23 at 16:53
  • You'll have gained a useful understanding when you know how to explain why this happens @darkchampionz – TKoL Mar 06 '23 at 16:56
  • https://stackoverflow.com/questions/63076634/how-is-settimeout-called-in-a-for-loop-js – epascarello Mar 06 '23 at 16:57

3 Answers3

3

Note how the code below sets a distinct timeout duration for each loop.

for (let i = 10; i >= 0; i--) {
    setTimeout(function() {
        console.log(i);
    }, 1000*(10-i)); // '10-i' staggers your timeouts
}

Your code was setting 11 timeouts to all fire at the same time after 1 second.

Marc
  • 11,403
  • 2
  • 35
  • 45
1

The reason that all the numbers are logged instantly is that the setTimeout() function schedules a function to be executed after a given delay, but it does not block the execution of the loop. As a result, all the setTimeout() functions are scheduled almost at the same time and execute after a delay of 1 second, effectively logging the same value (0) 11 times.

0

As others have pointed out the issue you are having is all your timeouts are being fired at the same time. You could stagger them like Marc suggested or you could implement an interval. Here is a code snippet of this implemented with an Interval which could be argued would be the correct tool to use in this situation.

// How many ticks you want
let tickCount = 10;
// What the current tick count is
let currentTick = 0;
// Vairable to store the interval id
let tickInterval;

// Function to handle the tick of the clock
function Tick(){
    // Check if we are still ticking
    if ((tickCount - currentTick) >= 0){
    // Log the current number of ticks left
    console.log(tickCount - currentTick);
    // Increment the current tick
    currentTick++;
  } else {
    // Clear the interval
        window.clearInterval(tickInterval);  
  }
}

// Start the interval
tickInterval = window.setInterval(Tick, 1000);
Adam H
  • 1,750
  • 1
  • 9
  • 24