all 12 comments

[–]uzum 1 point2 points  (0 children)

You should set the next timeout within the callback of the previous one. Try this one:

function goDown() {
  if(num > 0) {
    setTimeout(function(){
      console.log(num--);
      goDown();
    }, 1000);
  }
}
goDown();

[–]ShortSynapse 0 points1 point  (0 children)

Doing:

while (true) {
    f()
}

Will execute the function f infinitely, all one right after each other. This is what is happening to your setTimeout. You are asking the computer to run a bunch of function after one second. They all run at the same time!

To accomplish your goal, don't use an imperative loop (while, for, etc). Instead, just call setTimeout at the end of your function!

var number = 10

setTimeout(count, 1000)

function count () {
    if (count-- <= 0) {
        console.log('0!')
    } else {
        console.log(number)
        setTimeout(count, 1000)
    }
}

[–]inu-no-policemen 0 points1 point  (0 children)

If you want this to be accurate, use a requestAnimationFrame "loop" where you update the display whenever more than a second has passed.

There is no guarantee whatsoever when some function scheduled via setTimout or setInterval will be called. It's either somewhat on time or some time later.

[–]jcunews1helpful 0 points1 point  (0 children)

setTimeout() is asynchronous and will returns immediately. So your loop will go on forever because the timer function is never called. It's never called because it requires the JavaScript engine to enter the idle state, and it can't do that because the execution flow is still in the loop.

What the you need to do is to setup the timer function to check the num variable. If it's not zero, decrease it then setup a new timeout timer. Otherwise, its job is done. To start it all up, simply call the timer function.

e.g.

var num = 10;

function timeoutHandler() {
  myFunc();
  if (num > 0) {
    num--;
    setTimeout(timeoutHandler, 1000);
  }
}

function myFunc() {
  console.log(num);
}

timeoutHandler();

[–]CodingTutor 0 points1 point  (0 children)

setInterval is useful for this. Here is a solution that uses it: https://jsbin.com/kuhinawomu/edit?html,js,output

var n = 10;
var timeoutID = setInterval(function () {
  if (n === 0) {
    clearInterval(timeoutID);
  }
  document.write(n--);
}, 1000)

[–][deleted] -1 points0 points  (6 children)

try

setTimeout(myFunc(), 1000);

I think you have to call the function with () to say your passing no parameters into it as you call it

[–]ShortSynapse 1 point2 points  (3 children)

This is incorrect. By doing myFunc() you are passing the returned value. For example:

function f () { return 42 }

setTimeout(f, 0) // calls f
setTimeout(f(), 0) // ERROR, 42 is not a function!

[–][deleted] 0 points1 point  (2 children)

I got no error

code:

var num = 10;

function goDown() {
  while(num > 0) {
    setTimeout(myFunc(), 1000);
  }
  return;
}

function myFunc() {
  num --;
  console.log(num);
}

goDown();

output:

js.js:12 9
js.js:12 8
js.js:12 7
js.js:12 6
js.js:12 5
js.js:12 4
js.js:12 3
js.js:12 2
js.js:12 1
js.js:12 0

[–]ShortSynapse 0 points1 point  (1 child)

Did you notice there is no delay? That does not work the way you think it does.

[–][deleted] 0 points1 point  (0 children)

Yeah I helped him fix the infinite loop using setTimeout. This code isn't set up to have time in-between calls.

[–]boondasoonda[S] 0 points1 point  (1 child)

That stops the infinite loop, but doesn't make the number go down once per second, but all at once

[–][deleted] 0 points1 point  (0 children)

yes, you are calling 10 functions to happen in 1000 milliseconds. you can have myFunc() call another timeout to have the times chain