DEV Community

Discussion on: JavaScript recurring timers with setInterval

Collapse
 
peerreynders profile image
peerreynders

meaning they can overlap and cause issues.

Function executions don't overlapโ€”they just pile up. An interval of 100 may suggest starting times around 100, 200, 300, and 400 but the reality is that setInterval can continue to queue up work faster than the work can be processed. So the work actually starts at 100, 250, 350, and 550 (or even later if in between interval tasks the event loop processes some other events, promises resolve etc.).

function runBurner() {
  let i = 0;
  const log = makeLogger(document.timeline.currentTime);

  function doWork(pass) {
    switch (pass) {
      case 1:
      case 3:
        burnThread(100);
        return pass > 1;

      case 0:
        burnThread(150);
        return false;

      case 2:
        burnThread(200);
        return false;
    }
    return true;
  }

  function burner() {
    const pass = i++;

    log('entry', pass);
    const done = doWork(pass);
    log('exit', pass);

    if (done) clearInterval(intervalID);
  }

  const intervalID = setInterval(burner, 100);
}

runBurner();

/*
  Something like:

   entry(0): 114.58ms
    exit(0): 265.08ms
   entry(1): 265.38ms
    exit(1): 365.08ms
   entry(2): 365.88ms
    exit(2): 568.08ms
   entry(3): 568.28ms
    exit(3): 668.08ms
 */

//---
function burnThread(t) {
  const start = Date.now();
  while (Date.now() - start < t);
}

function makeLogger(start) {
  const nf = new Intl.NumberFormat(navigator.languages, {
    minimumFractionDigits: 2,
    maximumFractionDigits: 2,
    style: 'unit',
    unitDisplay: 'narrow',
    unit: 'millisecond',
  });

  return (name, count) => {
    const label = `${name}(${count})`.toString().padStart(8, ' ');
    const time = nf.format(performance.now() - start).padStart(8, ' ');
    console.log(`${label}: ${time}`);
  };
}
Enter fullscreen mode Exit fullscreen mode

The "overlapping animation" scenario could happen with concurrent but distinct animations stepping recursively through requestAnmationFrame() but there each animation step is a separately scheduled function - the entire animation isn't one single continuously running function.

Collapse
 
dailydevtips1 profile image
Chris Bongers

Ah yes, but for your eyes it would cause overlap depending on your animations ofcourse.
It would pile up and freak out, which is rarely what you'll want.

Thanks for the detailed explanation here :)