Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling functions with setTimeout()

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?

like image 319
Alex Hwang Avatar asked Sep 27 '10 01:09

Alex Hwang


People also ask

What is the use of setTimeout () in JavaScript?

setTimeout() The global setTimeout() method sets a timer which executes a function or specified piece of code once the timer expires.

Does setTimeout use callback?

The setTimeout() is a method of the window object. The setTimeout() sets a timer and executes a callback function after the timer expires.

Is setTimeout a function or a method?

Definition and Usage. The setTimeout() method calls a function after a number of milliseconds. 1 second = 1000 milliseconds.


1 Answers

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); } } 
like image 189
Peter Ajtai Avatar answered Sep 19 '22 19:09

Peter Ajtai