As far as I can tell, these two pieces of javascript behave the same way:
Option A:
function myTimeoutFunction()
{
doStuff();
setTimeout(myTimeoutFunction, 1000);
}
myTimeoutFunction();
Option B:
function myTimeoutFunction()
{
doStuff();
}
myTimeoutFunction();
setInterval(myTimeoutFunction, 1000);
Is there any difference between using setTimeout and setInterval?
setTimeout(function, milliseconds ) Executes a function, after waiting a specified number of milliseconds. setInterval(function, milliseconds ) Same as setTimeout(), but repeats the execution of the function continuously.
We all know that passing a string to setTimeout (or setInterval ) is evil, because it is run in the global scope, has performance issues, is potentially insecure if you're injecting any parameters, etc. So doing this is definitely deprecated: setTimeout('doSomething(someVar)', 10000);
why is setInterval inaccurate? As we know, setTimeout means to run the script after the minimum threshold (MS unit), and setInterval means to continuously execute a specified script with the minimum threshold value period. Note that I use the term minimum threshold here because it is not always accurate.
setImmediate() and setTimeout() are similar, but behave in different ways depending on when they are called. setImmediate() is designed to execute a script once the current poll phase completes. setTimeout() schedules a script to be run after a minimum threshold in ms has elapsed.
They essentially try to do the same thing, but the setInterval
approach will be more accurate than the setTimeout
approach, since setTimeout
waits 1000ms, runs the function and then sets another timeout. So the wait period is actually a bit more than 1000ms (or a lot more if your function takes a long time to execute).
Although one might think that setInterval
will execute exactly every 1000ms, it is important to note that setInterval
will also delay, since JavaScript isn't a multi-threaded language, which means that - if there are other parts of the script running - the interval will have to wait for that to finish.
In this Fiddle, you can clearly see that the timeout will fall behind, while the interval is almost all the time at almost 1 call/second (which the script is trying to do). If you change the speed variable at the top to something small like 20 (meaning it will try to run 50 times per second), the interval will never quite reach an average of 50 iterations per second.
The delay is almost always negligible, but if you're programming something really precise, you should go for a self-adjusting timer (which essentially is a timeout-based timer that constantly adjusts itself for the delay it's created)
Is there any difference?
Yes. A Timeout executes a certain amount of time after setTimeout() is called; an Interval executes a certain amount of time after the previous interval fired.
You will notice the difference if your doStuff() function takes a while to execute. For example, if we represent a call to setTimeout/setInterval with .
, a firing of the timeout/interval with *
and JavaScript code execution with [-----]
, the timelines look like:
Timeout:
. * . * . * . * .
[--] [--] [--] [--]
Interval:
. * * * * * *
[--] [--] [--] [--] [--] [--]
The next complication is if an interval fires whilst JavaScript is already busy doing something (such as handling a previous interval). In this case, the interval is remembered, and happens as soon as the previous handler finishes and returns control to the browser. So for example for a doStuff() process that is sometimes short ([-]) and sometimes long ([-----]):
. * * • * • * *
[-] [-----][-][-----][-][-] [-]
• represents an interval firing that couldn't execute its code straight away, and was made pending instead.
So intervals try to ‘catch up’ to get back on schedule. But, they don't queue one on top of each other: there can only ever be one execution pending per interval. (If they all queued up, the browser would be left with an ever-expanding list of outstanding executions!)
. * • • x • • x
[------][------][------][------]
x represents an interval firing that couldn't execute or be made pending, so instead was discarded.
If your doStuff() function habitually takes longer to execute than the interval that is set for it, the browser will eat 100% CPU trying to service it, and may become less responsive.
Which do you use and why?
Chained-Timeout gives a guaranteed slot of free time to the browser; Interval tries to ensure the function it is running executes as close as possible to its scheduled times, at the expense of browser UI availability.
I would consider an interval for one-off animations I wanted to be as smooth as possible, whilst chained timeouts are more polite for ongoing animations that would take place all the time whilst the page is loaded. For less demanding uses (such as a trivial updater firing every 30 seconds or something), you can safely use either.
In terms of browser compatibility, setTimeout predates setInterval, but all browsers you will meet today support both. The last straggler for many years was IE Mobile in WinMo <6.5, but hopefully that too is now behind us.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With