3

The following function shows the alert every 5 seconds:

function foo() {
    bar="foo";
    alert (bar);

    setTimeout(foo, 5000);
}

foo();

However, when I add arguments to the function and call from setTimeout, it no longer waits 5 seconds, it just alerts endlessly without any delay:

function foo(bar) {
    bar="foo";
    alert (bar);

    setTimeout(foo(bar), 5000);
}

foo();

Why is this and how can I loop through the function with a delay while passing arguments?

Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
dlofrodloh
  • 1,728
  • 3
  • 23
  • 44
  • Possible duplicate of [How can I pass a parameter to a setTimeout() callback?](http://stackoverflow.com/questions/1190642/how-can-i-pass-a-parameter-to-a-settimeout-callback) – tckmn Dec 19 '15 at 22:19
  • 1
    `foo(bar)` isn't a function. You've invoked a function and by definition, that invoked function returns something whether the return statement is there or not. – Quy Dec 19 '15 at 22:20

3 Answers3

7

JavaScript thinks you want to call foo(bar) immediately then pass its result into setTimeout(), which isn't what you mean. Instead, you should create an anonymous function with your call inside it, like this:

function foo(bar) {
    bar = "foo";
    alert(bar);

    setTimeout(function() {
        foo(bar)
    }, 5000);
}
TwoStraws
  • 12,862
  • 3
  • 57
  • 71
6

It's not working because you are invoking the function when using setTimeout(foo(bar), 5000).

You could use the .bind() method to pass the bar variable:

setTimeout(foo.bind(this, bar), 5000);

The first parameter is the value of this to be passed to the function. It can be null if you don't need it. The following parameters are the arguments that are passed. In this case, bar is the first argument.

Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
5

You could use the parameters arguments (after the 2nd argument):

setTimeout(foo, 5000, bar);

Basically, any arguments after the 2nd argument are passed down to the function supplied in the first argument.

MinusFour
  • 13,913
  • 3
  • 30
  • 39