Search code examples
javascriptd3.jstimer

Does d3.timer wait for the callback to complete before re-running it?


The documentation for d3.timer reads:

d3.timer(callback[, delay[, time]]) <>

Schedules a new timer, invoking the specified callback repeatedly until the timer is stopped. An optional numeric delay in milliseconds may be specified to invoke the given callback after a delay; if delay is not specified, it defaults to zero. The delay is relative to the specified time in milliseconds; if time is not specified, it defaults to now.

What does "invoking the specified callback repeatedly" mean? More precisely, does d3.timer wait for the callback to finish, and then runs it again?


Solution

  • That depends on what you mean by "wait for the callback to finish". Is it a very slow function that runs synchronously (and thus continuously)? Then yes.

    d3.timer(() => {
      const now = Date.now();
      while(Date.now() - now < 1000) {}; // do nothing, but keep the process engaged
      console.log("Ping");
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

    But if it is an asynchronous function - like an API call - which deschedules the process, then no.

    let i = 0,
      j = 0;
    d3.timer(() => {
      // Break after 100 iterations
      if(j > 100) {
        return true;
      }
    
      // do nothing, but release the process
      // so the thread can go do other things
      console.log("Scheduled promise", j);
      j++;
      
      return new Promise((resolve) => {
        setTimeout(() => {
          resolve(i);
          console.log("Resolved promise", i);
          i++;
        }, 1000);
      });
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>