Scheduling in JavaScript

Scheduling in JavaScript​

setTimeout:

  • runs only once, after a time interval,
  • since it is designed to run only once, it doesn't need to stop.
  • Receives function reference/name, not function call
function sayHi(name) {
  console.log(`Hi ${name}`);
}

const timerId = setTimeout(sayHi, 100, "John");

// clearing a timeOut
clearTimeout(timerId);

the delay:

  • added in ms (miliseconds),
  • it's the minimum time after which the code will be executed,
  • can be 0

Scheduling in JavaScript​

function sayHi() {
  console.log(`Hi John`);
}

const timerId = setTimeout(sayHi, 100);

// clearing a timeOut
clearTimeout(timerId);

execution:

  • setTimeout: as soon as the JS sees a setTimeout, it sends it to webAPIs,
  • in the webAPIs, the timer expires,
  • after the timer expires, the code inside is send to callback queue,
  • once the call-stack is empty, the code from callback queue is send to call stack for execution

Scheduling in JavaScript​

execution:

  • setInterval: similar to setTimeout,
  • the only difference: once the setInterval is sent to webAPIs, as the timer expires, a copy of the executable code is send to callback queue, and the timer gets reset
  • the original setInterval remains in webAPIs to execute repeatedly

0ms delay:

  • even though setTimeout was called with a delay of zero 0, it's placed on the callback queue and scheduled to run at the next opportunity; not immediately.
  • Currently-executing code must complete before functions on the callback queue are executed,
  • schedule the call “as soon as possible, but after the current script is complete”

Scheduling in JavaScript​

function foo() {
  console.log("foo has been called");
}
setTimeout(foo, 0);
console.log("After setTimeout");


// "After setTimeout"
// "foo has been called"

Nesting setTimeout instead of setInterval:

  • The setTimeout here schedules the next call right at the end of the current one,
  • Nested setTimeout allows to set the delay between the executions more precisely than setInterval,
  • The nested setTimeout guarantees the fixed delay (here 100ms).
  • That’s because a new call is planned at the end of the previous one.

Scheduling in JavaScript​

/** instead of:
let timerId = setInterval(
() => alert('tick'), 2000);
*/
let timerId = setTimeout(function tick() {
  alert('tick');
  timerId = setTimeout(tick, 2000);
}, 2000);

// example 2
let start = Date.now();
let times = [];

setTimeout(function run() {
  // remember delay from the previous call
  times.push(Date.now() - start);

  // show the delays after 100ms
  if (start + 100 < Date.now()) alert(times);
  else setTimeout(run); // else re-schedule
});
  • Please note that all scheduling methods do not guarantee the exact delay.
  • For example, the in-browser timer may slow down for a lot of reasons:
    - The CPU is overloaded.
    - The browser tab is in the background mode.
    - The laptop is on battery saving mode.
    - All that may increase the minimal timer resolution (the minimal delay) to 300ms or even 1000ms depending on the browser and OS-level performance settings.
  • The browser limits the minimal delay for five or more nested calls of setTimeout or for setInterval (after 5th call) to 4ms. That’s for historical reasons.

Scheduling in JavaScript​