Node.js morsel for today: Understanding Node.js timers

From the Node.js documentation, Node.js Timers are described as scheduling functions to be called at some future period of time.

Broadly, they refer to the setTimeout, setInterval and setImmediate functions. They are further broken into subgroups defined by the phase of the event loop their handle callbacks are executed.

What are Handle callbacks?

Handles represent long-lived objects capable of performing certain operations while active.

Invoking a timer creates a ref’ed handle by default. A ref’ed handle is an active handle with the callback not yet executed.

const immediateHandle = setImmediate(() => {
  console.log('SetImmediate Handle Callback')
});
// Log immediateHandle gives us the handle object
// Immediate {
//   _idleNext: null,
//   _idlePrev: null,
//   _onImmediate: [Function (anonymous)],
//   _argv: undefined,
//   _destroyed: false,
//   [Symbol(refed)]: true,
//   [Symbol(asyncId)]: 2,
//   [Symbol(triggerId)]: 1
// }

The immediateHandle logged out in the code snippet shows 2 properties that are important to the Event Loop.

  • _onImmediate: this is the callback that will be invoked. setTimeout has _onTimeout.

  • Symbol(refed): this shows that the handle is active. It becomes null when not active.

The timers Event Loop phase is where the callbacks of the handles created by the setTimeout and setInterval functions are called.

The check Event Loop phase is where the callbacks of the handles created by the setImmediate functions are called.

The _onImmediate callback is invoked on the next iteration of the Event Loop.

The _onTimeout callback is invoked when the current Event Loop's iteration concept of now is ahead of the scheduled time based on the setTimeout threshold.