frosty
frosty

Reputation: 2649

Using setTimeout correctly

I'm trying to make it so that it document.write() 9, then pause 1 second, writes 8, then pause 1 second, write 7, then pause 1 second, and so on and so forth until it hits 0. But right now it just prints the entire thing out at once. What am I doing wrong?

var delay = function(){
setTimeout(delay, 1000); // check again in a second
}

var count = 10;
while (count > 0) {
count--;
delay();
document.write(count);
}

9876543210

Upvotes: 0

Views: 50

Answers (3)

Saif
Saif

Reputation: 3452

Here's an example using setInterval and console.log

var count = 9;

var timer = setInterval(delay, 1000);

function delay() {
  console.log(count--);
  if(count<0)
    clearInterval(timer);
}

Upvotes: 1

CertainPerformance
CertainPerformance

Reputation: 370639

Two issues:

  • Calling setTimeout only queues up a function to execute once the timeout expires - it doesn't pause the main thread.

  • document.write is document.wrong, usually - if the document has already been parsed, it will be replaced with the new HTML string. Use proper DOM methods instead.

You could await promises every second and append spans:

const delay = () => new Promise(res => setTimeout(res, 1000));
(async () => {
  let count = 10;
  while (count > 0) {
    await delay();
    count--;
    document.body.appendChild(document.createElement('span')).textContent = count;
  }
})();

You could also (synchronously) set timeouts for each iteration:

for (let count = 9; count >= 0; count--) {
  setTimeout(() => {
    document.body.appendChild(document.createElement('span')).textContent = count;
  }, (10 - count) * 1000);
}

Upvotes: 3

Herman Starikov
Herman Starikov

Reputation: 2756

setTimeout is asynchronous, it does not pause execution.

var count = 10;
var delay = function(){
  if (count > 0) {
    count--;
    document.write(count);
    setTimeout(delay, 1000); // check again in a second
  }
}
delay();

This could work, but I don't think document.write works after page finished loading. Meaning you cannot call it in a timeout callback.

Upvotes: 1

Related Questions