Published on

Why I consider setInterval to be harmful

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 setTimeout.

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 setTimeout delay appropriately. It is important to note, however, that JavaScript timers are not high-precision. You will never ever get absolutely even intervals, even if you use setInterval, for a variety of reasons (garbage collectors, the fact that JavaScript is single-threaded, solar flares, etc.). In addition, all current browsers will clamp the minimum timeout value to somewhere between 4ms and 15ms. So don’t worry too much about the difference!