Introduction

Async Hooks are a core module in Node.js that provides an API to track the lifetime of asynchronous resources in a Node application. An asynchronous resource can be thought of as an object that has an associated callback.

Examples include, but are not limited to: Promises, Timeouts, TCPWrap, UDP etc. The whole list of asynchronous resources that we can track using this API can be found here.

The Async Hooks feature was introduced in 2017, in Node.js version 8 and is still experimental. This means that backwards-incompatible changes may still be made to future releases of the API. That being said, it’s currently not deemed fit for production.

In this article, we will take a deeper look at Async Hooks - what they are, why they are important, where we can use them and how we can leverage them for a particular use case, that is, request context handling in a Node.js and Express application.

What are Async Hooks?

As stated earlier, the Async Hooks class is a core Node.js module that provides an API for tracking asynchronous resources in your Node.js application. This also includes tracking of resources created by native Node modules such as fs and net.

During the lifetime of an async resource, there are 4 events which fire and we can track, with Async Hooks. These include:

  1. init - Called during the construction of the async resource
  2. before - Called before the callback of the resource is called
  3. after - Called after the callback of the resource has been invoked
  4. destroy - Called after the async resource is destroyed
  5. promiseResolve - Called when the resolve() function of a Promise is invoked.

Below is a summarized snippet of the Async Hooks API from the overview in the Node.js documentation:

const async_hooks = require('async_hooks');

const exec_id = async_hooks.executionAsyncId();
const trigger_id = async_hooks.triggerAsyncId();
const asyncHook = async_hooks.createHook({
  init: function (asyncId, type, triggerAsyncId, resource) { },
  before: function (asyncId) { },
  after: function (asyncId) { },
  destroy: function (asyncId) { },
  promiseResolve: function (asyncId) { }
});
asyncHook.enable();
asyncHook.disable();

The executionAsyncId() method returns an identifier of the current execution context.

The triggerAsyncId() method returns the identifier of the parent resource that triggered the execution of the async resource.

The createHook() method creates an async hook instance, taking the aforementioned events as optional callbacks.

To enable tracking of our resources, we call the enable() method of our async hook instance which we create with the createHook() method.

We can also disable tracking by calling the disable() function.

Having seen what the Async Hooks API entails, let’s look into why we should use it.

#node #javascript #asynchronous

Using Async Hooks for Request Context Handling in Node.js
11.25 GEEK