0

On button click, I'm trying to set a timeout to call the same function again.

I tried setTimeout(f2(), 100), but this didn't work as expected. It immediately calls f2 again, not after 100ms. However, setTimeout("f2()", 100) worked.

What's the difference between the two?

function f2 () {
  setTimeout(f2(), 100)
  // this runs `f2` immediately, i.e., `100` has no effect
  // after a while, an error occurs

  setTimeout("f2()", 100)  // works
}
<input type="button" onclick="f2()">
royhowie
  • 11,075
  • 14
  • 50
  • 67
Sasayaku
  • 69
  • 5

4 Answers4

4

From MDN, WindowTimers.setTimeout allows for the following syntax:

var timeoutID = window.setTimeout(func, [delay, param1, param2, ...]);
var timeoutID = window.setTimeout(code, [delay]);

If you pass setTimeout a string, it will evaluate it. This is both slow and dangerous, so DO NOT do it. You are only asking for trouble. Instead, pass a function as the first parameter. For example:

// you can pass an anonymous function
setTimeout(function () { /* do something */ }, 420)

// or, a named function
// note how you don't pass an executed function, e.g., `someAwesomeFunc()`,
// UNLESS `someAwesomeFunc` returns a function
setTimeout(someAwesomeFunc, 9000)

Here's a more comprehensive example. Make sure to look at your console:

/*  ~~~ EXAMPLE #0 ~~~  */
// the passed string is evaluated
// DO NOTE DO THIS…EVER!
setTimeout('console.log("hi", new Date())', 1000)

/*  ~~~ EXAMPLE #1 ~~~  */
// an anonymous function is passed
// everything is bueno
setTimeout(function () {
  console.log('hi! #2', new Date())
}, 2000)

/*  ~~~ EXAMPLE #2 ~~~  */
// note how `getHi` *returns* an anonymous function
// that means `typeof getHi(420) === 'function'`
var getHi = function (num) {
  return function () {
    console.log('hi! #' + num, new Date())
  }
}
// as previously stated `getHi(420)` returns a function
// so this works in the same manner as example #2
setTimeout(getHi(420), 4200)

/*  ~~~ EXAMPLE #3 ~~~  */
var returnHi = function () { return 'hi!' }
// `returnHi` returns neither function nor code, so a syntax error is thrown
setTimeout(returnHi(), 5000)  // <-- doesn't work
royhowie
  • 11,075
  • 14
  • 50
  • 67
2

The first parameter of setTimeout() should be a function (or a code as string - not suggested).

When you call this setTimeout(fn(),t), the fn() will execute first and what you pass in setTimeout() is the result of fn() (by return keyword).

So fn() is not a function, but a result of function. A function must be fn.

You should call like this:

setTimeout(fn,t)

Pham Tung
  • 181
  • 1
  • 6
1

the first form runs f2 immediately and after 100 ms attempts to run the return value of f2 as a function. in your case that's undefined. the second form essentially evals the string you pass after 100 ms

Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
1

You want to pass a reference to a method, not a method. foo() is a method, foo is a reference. "foo" and "foo()" works the same.

Look for more info here: JavaScript.setTimeout

Community
  • 1
  • 1
Astrogat
  • 1,617
  • 12
  • 24