Calling functions with setTimeout()

javascript, settimeout

Solution

The first form that you list works, since it will evaluate a string at the end of `delay`. Using `eval()` is generally not a good idea, so you should avoid this.

The second method doesn't work, since you immediately execute a function object with the function call operator `()`. What ends up happening is that `playNote` is executed immediately if you use the form `playNote(...)`, so nothing will happen at the end of the delay.

Instead, you have to pass an anonymous function to setTimeout, so the correct form is:

setTimeout(function() { playNote(currentaudio.id,noteTime) }, delay);

Note that you are passing `setTimeout` an entire function expression, so it will hold on to the anonymous function and only execute it at the end of the delay.

You can also pass `setTimeout` a reference, since a reference isn't executed immediately, but then you can't pass arguments:

setTimeout(playNote, delay);

Note:

For repeated events you can use `setInterval()` and you can set `setInterval()` to a variable and use the variable to stop the interval with `clearInterval()`.

You say you use `setTimeout()` in a `for` loop. In many situations, it is better to use `setTimeout()` in a recursive function. This is because in a `for` loop, the variables used in the `setTimeout()` will not be the variables as they were when `setTimeout()` began, but the variables as they are after the delay when the function is fired.

Just use a recursive function to sidestep this entire problem.

Using recursion to deal with variable delay times:

  // Set original delay
var delay = 500;

  // Call the function for the first time, to begin the recursion.
playNote(xxx, yyy);

  // The recursive function
function playNote(theId, theTime)
{
    // Do whatever has to be done
    // ...

    // Have the function call itself again after a delay, if necessary
    //   you can modify the arguments that you use here. As an
    //   example I add 20 to theTime each time. You can also modify
    //   the delay. I add 1/2 a second to the delay each time as an example.
    //   You can use a condition to continue or stop the recursion

    delay += 500;

    if (condition)
    { setTimeout(function() { playNote(theID, theTime + 20) }, delay); }
}

Problem

Simply put... why does ``` setTimeout('playNote('+currentaudio.id+', '+noteTime+')', delay); ``` work perfectly, calling the function after the the specified delay, but ``` setTimeout(playNote(currentaudio.id,noteTime), delay); ``` calls the function playNote all at the same time? (these setTimeout()s are in a for loop) or, if my explanation is too hard to read, what is the difference between the two functions?

Original source

Related problems