Update 2011-03-01: I added the 3rd reason I inadvertently omitted from the original article.
I have been spending some time in jQuery chat lately, and something that comes up fairly often is the desire to repeat an action every n milliseconds. “No problem”, many will say. “Just use
setInterval.” I consider this to be terrible advice.
Reason #1: setInterval ignores errors.
setInterval has a nasty habit of not paying any attention to whether or not the code it calls generates errors. This means that if, for some reason, an error occurs in part of the code that is called by
setInterval, it will continue to call that code over and over again. Demo
Reason #2: setInterval does not care about network latency.
Let’s say you are polling a remote server for any new data on a fixed interval using AJAX. (Note: If you are doing this, you are probably doing it wrong; use backoff polling instead.) For some reason (server overload, temporary network connectivity loss, Slashdot effect, satellite/dial-up user, whatever), these requests are taking longer to complete than you thought they would.
setInterval doesn’t care. It will continue firing those requests off, over and over again, until your client’s network queue is filled up with AJAX calls. Demo
Reason #3: setInterval does not guarantee execution.
Unlike setTimeout, there is no guarantee that an interval will actually execute when you ask it to. If the function you call on an interval takes too long to complete, some invocations will simply end up being dropped. Demo
The solution is simple: setTimeout
Instead of using
setInterval, make the function call itself using
setTimeout at an appropriate moment. In both of the above demos, function
a does it wrong using
setInterval, and function
b does it more properly with
But what if I absolutely need the event to occur at the same interval every time?
If you want to ensure that your events are occurring on an ‘even’ interval, you can calculate the difference between your intended delay and the amount of time the last call took to complete and adjust your