80

I have this counter I made but I want it to run forever, it's really simple, what am I doing wrong here?

function timer() {
  console.log("timer!")
}

window.setInterval(timer(), 1000)
Ivar
  • 6,138
  • 12
  • 49
  • 61
computer_smile
  • 2,117
  • 2
  • 24
  • 42
  • 12
    The problem is `timer()` invokes the function-object that resulted from evaluating `timer` and then passes the result (`undefined`) to `setTimeout`. So, don't invoke it. Instead, just pass the function-object: `setInterval(timer, 1000)` –  Apr 16 '12 at 22:57
  • For the same problem with `setTimeout`, see [here](https://stackoverflow.com/q/7137401/1048572) or [there](https://stackoverflow.com/q/3800512/1048572). – Bergi Sep 08 '22 at 21:18

2 Answers2

125

You used a function call instead of a function reference as the first parameter of the setInterval. Do it like this:

function timer() {
  console.log("timer!");
}

window.setInterval(timer, 1000);

Or shorter (but when the function gets bigger also less readable):

window.setInterval( function() {
  console.log("timer!");
}, 1000)
Koen Peters
  • 12,798
  • 6
  • 36
  • 59
  • 3
    the answer correctly points out that the callback function should not have the "()" in the argument. – Kristian Apr 16 '12 at 22:42
  • 2
    According to https://developer.mozilla.org/en/Extensions/Common_causes_of_memory_leaks_in_extensions#Be_careful_with_setInterval.2FsetTimeout, the shorter version may cause memory leak. – Reci Apr 16 '12 at 22:46
  • 2
    @CrendKing Both versions have the exact same "issue" (also, that is for extensions and does not affect normal webpages/JS) as it is *object lifetime* that matters. –  Apr 16 '12 at 23:14
  • That's why I said "may", since OP does not specify his use case. Just pay attention if it is extracted from an Mozilla extension. – Reci Apr 16 '12 at 23:32
  • How can we change the interval value, for e.g. I have array[10, 5, 2] and want to call timer() based on the interval defined in array. Thanks! – Paresh Mar 09 '17 at 15:46
  • 1
    You can't with setInterval, but you can mimic this with the setTimeout function. – Koen Peters Mar 09 '17 at 20:10
13

setInterval and setTimeout must be used with callbacks, like:

setInterval(timer, 1000);

or unnamed functions:

setInterval( function() { console.log("timer!"); }, 1000 );

Why your code is not working - when you pass a function as argument to another function with brackets e.g. doSomething ( someFunc() ) you are passing the result of the function.

When the function is passed as object e.g. doSomething ( someFunc ) you are passing a callback. This way someFunc is passed as reference and it is executed somewhere in the calling function. This is the same as the pointers to functions in other languages.

A common mistake is to use the these two functions as shown at w3schools. This makes an implicit call to eval.

Bakudan
  • 19,134
  • 9
  • 53
  • 73