Skip to main content
6 of 8
Rollback to Revision 3
200_success
  • 144.2k
  • 22
  • 188
  • 473

Alternative to setInterval and setTimeout

Alternative to setInterval and setTimeout

JavaScript's setTimeout and setInterval are evil and not precise...

  1. both have a delay of various milliseconds http://www.andrewduthie.com/post/a-self-correcting-setinterval-alternative/

  2. both are very resource intensive as they execute several times every second.

A new alternative is requestAnimationFrame. it's less resource=intensive, does not slow down other stuff and it is disabled on page blur.

This makes it the perfect substitute for a modern setTimeout and setInterval.

So I wrote this functions:

Description

This functions use requestAnimationframe to check if the time is passed based on the elapsed Time calculated from Date.now. The time passed is more precise than the native functions and theoretically less resource intensive. Another advantage/disadvantage(depends) is that the functions are not executed on page blur.

Good for: animations, visual effects

Bad for: timers, clock

RafTimeout

window.rtimeOut=function(callback,delay){
 var dateNow=Date.now,
     requestAnimation=window.requestAnimationFrame,
     start=dateNow(),
     stop,
     timeoutFunc=function(){
      dateNow()-start<delay?stop||requestAnimation(timeoutFunc):callback()
     };
 requestAnimation(timeoutFunc);
 return{
  clear:function(){stop=1}
 }
}

RafInterval

window.rInterval=function(callback,delay){
 var dateNow=Date.now,
     requestAnimation=window.requestAnimationFrame,
     start=dateNow(),
     stop,
     intervalFunc=function(){
      dateNow()-start<delay||(start+=delay,callback());
      stop||requestAnimation(intervalFunc)
     }
 requestAnimation(intervalFunc);
 return{
  clear:function(){stop=1}
 }
}

Usage

var interval1,timeout1;
window.onload=function(){
 interval1=window.rInterval(function(){console.log('interval1')},2000);
 timeout1=window.rtimeOut(function(){console.log('timeout1')},5000);
}

/* to clear
interval1.clear();
timeout1.clear();
*/

Demo

http://jsfiddle.net/wZ9Z6/

QUESTIONS

  1. Normally I don't write functions inside functions, but in this case it's probably a good solution. What about memory leaks if I create hundreds of this time-based functions?

  2. Is there a better solution to clear those functions?

  3. For heavy animations and multiple intervals, timeouts I was thinking to activate a single requestAnimationFrame loop which check for intervals and timeouts inside a previously stored array... (but I think there should be no difference if there are just one requestAnimationframe or multiple). So how do the browsers handle those multiple requestAnimationframes?

Note:

if the code above does not work here is the original code.

window.rInterval=function(a,b){var c=Date.now,d=window.requestAnimationFrame,e=c(),f,g=function(){c()-e<b||(e+=b,a());f||d(g)};d(g);return{clear:function(){f=1}}}//callback,delay
window.rtimeOut=function(a,b){var c=Date.now,d=window.requestAnimationFrame,e=c(),f,g=function(){c()-e<b?f||d(g):a()};d(g);return{clear:function(){f=1}}}
cocco
  • 303
  • 1
  • 3
  • 12