DEV Community

MOYED
MOYED

Posted on

10. setTimeout, setInterval, and requestAnimationFrame

setTimeout, setInterval, and requestAnimationFrame are 3 most common APIs for scheduling call.

SetTimeout & setInterval

Definition

  • setTimeout : allows us to run function once after given time.

- setInterval : allows us to run function repeatedly starting after given time, repeating continuously at the interval.

setTimeout

syntax

setTimeout(callback, delay, arg1, arg2,...)

Parameter from arg1, arg2,.. is optional.

Call to setTimeout returns "timer identifier" timerId.

We can use clearTimeout to cancel execution. The callback given as a parameter stays in memory untill we call clearTimeout.


setInterval

Most parts of syntax is similar to setTimeout. Instead of clearTimeout, we use clearInterval.

using setInterval & setTimeout for repeating function for given time period


 jsx
let timerId = setInterval(()=>alert('tick'), 2000);

setTimeout(()=>{clearInterval(timerId); alert('stop');}, 5000);


Enter fullscreen mode Exit fullscreen mode

In above snippet, we planned to print 'tick' for every 2sec, and it stops after 5sec.


Nested setTimeout

For scheduling repeated function, there is a alternative for setInterval. It is using nested setTimeout. The advantage is that we can set delay between executions more precisely. It's more flexible.


 jsx
let delay = 2000;
let timerId = setTimeout(function tick() {
  delay = 2000;
  console.log('tick');
  timerId = setTimeout(tick, 2000); // (*)
  const random = Math.random(0,1000);
  console.log(random)
  if(random%2 == 0) {
    delay = 1000;
  }
}, delay);


Enter fullscreen mode Exit fullscreen mode

setInterval vs Nested setTimeout

Note that both of methods do not guarantee exact delay of given time.

setInterval

setInterval calls function in given interval. It only guarantees that function will be passed to STACK in exeact interval. For example, if the given interval is 1sec, it means that function is called every 1sec.

One big disadvantage of this mechanism is that It doesn't guarantees the interval of execution. If the previous function ofsetInterval's execution takes lots of time, the callback of setInterval can be executed unexepectedly.

Nested setTimeout

On the other hand, Nested setTimeout guarantees untill our method gets fully executed it will never be sent for another execution.

Other

Another alternative for handling repeating callback is using aync setInterval.


 jsx
const setIntervalAsync = (fn, ms) => {
  fn().then(() => {
    setTimeout(() => setIntervalAsync(fn, ms), ms);
  });
};

setIntervalAsync(() => fetch(/* blah */), 3000);


Enter fullscreen mode Exit fullscreen mode

Zero delay setTimeout

If we set interval of setTimeout to 0, it is not executed right away. The reason is because setTimeout is handled by Web API and task queue and then pushed to stack. So, it is scheduled 'right after' the current script. If current script is over, which means that stack is empty, then it is executed.


requestAnimationFrame

requestAnimationFram is used when we have to handle repeated animation changes in javascript.

Why use requestAnimationFrame?

Problems with setTimeout & setInterval

  • As mentioned above, the interval between animation is inconsistent.

  • Layout thrashing happens. Layout thrashing is when browser is froced to perform unnecessary reflows of the page before the user's screen is able to display the changes.

Benefits of requestAnimationFrame

  • It allows me to execute code on the enxt available screen repaint, which syncs with browser & hardware. It makes smoother animation.

  • If the page is in inactive tabls, animation stops automatically, whcih saves system resources.

  • Battery-friendly.

syntax

requestAnimationFrame(callback)

Runs callback when screen is ready to accept the next screen repaint.
The callback function automatically passes timestamp which indicates the precise time requestAnimationFrame is called.
requestAnimationFrame returns non 0 integer that can be passed to cancelAnimationFrame for cancelling it.

To repeatedly call callback function, we should use it recursively.


 jsx
function repeat(){
  // animation
   requestAnimationFrame(repeat);
}

requestAnimationFrame(repeat);


Enter fullscreen mode Exit fullscreen mode

Top comments (0)