3

A couple years ago I was warned against using setInterval for long periods of time as it supposedly would cause the browser to hang if the called function ran longer than the designated interval, and would then not be able to catch up:

setInterval( function(){
  foo = 'bar_' + i++;
}, 1 );

Now, I'm aware that adding lots of code in a loop could cause the browser to hang anyway, and that blocking code like alert, prompt, and confirm will stop the code in it's tracks, but is there any good reason to avoid setInterval?

Note: I am aware of how to do recursive setTimeout calls (as that's what I've been using), this question is my trying to figure out if it's still worth using them, or whether setInterval can be used safely.

zzzzBov
  • 174,988
  • 54
  • 320
  • 367
  • Chrome has had issues with setInterval. See here: http://code.google.com/p/chromium/issues/detail?id=25892. Personally, I just use a recursive setTimeout (closures work great for this) instead. –  Mar 29 '11 at 22:40

2 Answers2

21

The reason setInterval is bad is because it will try to execute the code every X MS regardless of what's going on in the thread. So if you have:

setInterval( complexFunction, 1 ); // complexFunction takes >1 MS to complete

...you may end up with setInterval trying to re-execute several times before even its own code is complete! However, you can use setTimeout similarly and avoid this problem:

setTimeout( complexFunction, 1 );

function complexFunction() {
  // complex code
  setTimeout( complexFunction, 1 );
}

...now complexFunction will only call itself again once its own code is complete, so if its own code takes longer than 1 MS to complete you won't have any backlog to deal with like you would with setInterval

mVChr
  • 49,587
  • 11
  • 107
  • 104
  • That's exactly the same information that I had heard. Is there any source or demo code to demonstrate that this is still an issue? – zzzzBov Mar 29 '11 at 23:13
  • It depends on the complexity of the code and the speed of the browsers you need to account for. You can always try throwing any of the V8 benchmarks ( http://v8.googlecode.com/svn/data/benchmarks/v3/run.html ) into a setInterval with 1 ms repeat and see how nastily it breaks. – mVChr Mar 29 '11 at 23:26
  • 5
    This is **absolutely incorrect**. If the browser is busy the entire time an interval expires twice, the interval invocation is **dropped**, not queued up. [See example.](http://jsfiddle.net/josh3736/CyVdz/) – josh3736 Nov 12 '12 at 02:11
  • 2
    I know this is an old thread but I will note that I ran into this issue terribly doing intervals with ajax requests. I solved it by using timeouts and nesting the calls so that the timeout is reset when the final one resolved. It wasn't a problem on the desktop but I ran into it on tablets (pretty bad tablets). – Mitchell Ingram Dec 11 '15 at 21:38
  • won't this code, in case of infinite recursion eat, all machine resources, like stack memory, after long time? – Vladyslav Nikolaiev May 14 '16 at 12:36
-1

it always better to use setTimeout in a loop so you know exactly when to continue timing:

foo();
function foo(){

   setTimeout (function(){
      foo = 'bar_' + i++;
      foo();
     }, 1 );

} 

otherwise as you said above, the browser will have to catch up and since ur loop is in infinitum, it might not.

Naftali
  • 144,921
  • 39
  • 244
  • 303
  • 1
    This is **absolutely incorrect**. If the browser is busy the entire time an interval expires twice, the interval invocation is **dropped**, not queued up; therefore a browser will not try to "catch up". [See example.](http://jsfiddle.net/josh3736/CyVdz/) – josh3736 Nov 12 '12 at 02:18
  • @josh3736 did you even **look** at your script????! you clear the interval after ten seconds! – Naftali Nov 12 '12 at 14:02
  • 3
    @josh3736 if they were dropped, you'd see 1, 3, 5, etc in the spin numbers. You're not proving anything in your fiddle. – Florian Margaine Nov 12 '12 at 14:16
  • @FlorianMargaine: No, the fiddle counts how many times `spin` is invoked, *not* how many intervals should have passed. It's not supposed to count odd. – josh3736 Nov 12 '12 at 15:14
  • @Neal: For the purposes of a demo, we have to stop spinning somehow. You could just as easily make a button that clears the interval rather than setting a timeout to clear it. – josh3736 Nov 12 '12 at 15:15
  • ...for further reading, see [John Resig's *How JavaScript Timers Work*](http://ejohn.org/blog/how-javascript-timers-work/). – josh3736 Nov 12 '12 at 15:16