Skip to content
+91-7795206615
|
info@habilelabs.io

  • Home
  • About
  • Services
    • Custom Application Development
    • UI/UX Designing
    • Web Application Development
    • Offshore Product Services
    • Technical Outsourcing
    • ERP Services
  • Company
    • Careers
    • Case Studies
  • Specialization
    • Frontend Frameworks
      • Angular
      • ReactJS
      • VueJS
      • HTML / CSS
      • Javascript /Jquery
      • Bootstrap
      • Material design
    • Backend Frameworks
      • NodeJS
      • Meteor
      • GraphQL
      • Loopback
      • Salesforce
      • Spring Boot
      • Odoo
      • Laravel
    • Database / ORM
      • MySQL
      • PostgreSQL
      • Oracle
      • MongoDB
      • Google Firebase
      • Mongoose
      • Sequelize
      • Hibernate / JPA
    • Languages
      • Java Script
      • Dot Net
      • Java
      • Python
      • C / C++
      • PHP
      • AI / ML
      • Type Script
    • Mobile Frameworks
      • Ionic
      • Native Script
      • Native Android App
      • Native iOS App
      • Google Flutter
      • React Native
  • Blog
  • Hire Us

Async Hooks in Node.js- Features and Use Cases

Categories

  • Angular
  • Business Strategies
  • Cloud Services
  • CRM
  • Design Pattern
  • E-commerce
  • ERP Applications
  • Javascript
  • Meteor
  • Mobile development
  • Mongo DB
  • Node JS
  • Odoo
  • Our Partners
  • PHP
  • React
  • SAAS
  • Salesforce
  • SAP
  • Selenium
  • Tech stack Migration
  • Testing
  • UI-UX Design
  • Uncategorized
  • VAPT
  • Visualforce
  • Web Development
  • Web Security

Categories

  • Angular
  • Business Strategies
  • Cloud Services
  • CRM
  • Design Pattern
  • E-commerce
  • ERP Applications
  • Javascript
  • Meteor
  • Mobile development
  • Mongo DB
  • Node JS
  • Odoo
  • Our Partners
  • PHP
  • React
  • SAAS
  • Salesforce
  • SAP
  • Selenium
  • Tech stack Migration
  • Testing
  • UI-UX Design
  • Uncategorized
  • VAPT
  • Visualforce
  • Web Development
  • Web Security
async-hooks-in-nodejs

Node.js 8 version released a new module called async_hooks. It provides an easy-to-use API to track the lifetime of async resources in Node.js applications.

The Node team introduced this module back in 2017. However, it is still in the experimental state.

The asynchronous resources mentioned here are the objects created by Node.JS that have associated callback and can be called multiple times. Some examples of asynchronous resources are Timeouts, Promises, TCPWRAP, Immediates, etc.

We’ll learn more about Async hooks and their use cases in this blog. Let’s get going then-

Why Do We Need Async Hooks?

Async process creates async resources, for example, file read, database read operation, external API call. So naturally async resources keep track of callbacks, once the process completes. But, if we need to track the async resource like what is happening in the middle of an async resource execution, we don’t have any way to do that. 

The typical lifecycle of such an async resource is similar to this:

Life cycle of an async resource

To solve this concern, Nodejs provided async hooks to spy on life cycle of async resources. 

Enough talking, show me the code!

Hello word to async hooks-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<strong>const </strong>fs = require(<strong>'fs'</strong>);
 
<strong>const </strong>{ fd } = process.stdout;
<strong>const </strong>async_hooks = require(<strong>'async_hooks'</strong>)
<strong>function </strong>init(asyncId, type, triggerAsyncId, resource) {
    fs.writeSync(fd, <strong>`Init callback async id --&gt; </strong>${asyncId} <strong>\n`</strong>);
}
<strong>function </strong>destroy(asyncId) {
    fs.writeSync(fd, <strong>`Destroy callback async id --&gt;</strong>${asyncId} <strong>\n`</strong>);
}
<strong>const </strong>asyncHook = async_hooks.createHook({ init: init, destroy: destroy });
asyncHook.enable();
 
<em>setTimeout</em>(()=&gt;{
    <em>//do nothing
</em>}, 1000);
1
//output<br>/*<br>Init callback async id --&gt; 4<br>Destroy callback async id --&gt;4<br>*/

In the example above, we have setTimeout is making an async operation. We have created two async hooks init and destroy. When we execute the code, we can see that it is calling init first, and then callsdestroy function. You might be wondering why we are using fs.writeSync to print on console rather than using console.log.

Console.log is async function itself, so this will cause async hooks again, and will cause infinite recursion. So we can not use any async code inside async hooks. We will discuss it later on again in this article. 

Async Hooks APIs

Essentially, the async hooks API provides these five key event functions that we call during different time and instances of the resource’s lifecycle, to track the async resources. 

Key Asynchronous Hooks

You have to specify the event that you want to trigger out of the following while creating an instance.

All the callbacks are optional. Let’s make this statement a little more obvious- It means if the cleanup data of the resource is to be tracked, then you only need to pass the destroy callback.

init

The init callback is called whenever a call is created that has the possibility of triggering an asynchronous event. Just for the record, at this point, we’ve already associated the hook with an async resource.

init callback receives these parameters when called-

  • asyncId: Each async resource, when identified, gets a unique ID.
  • type: It depicts the type of the async resource in string form that triggered init callback.
  • triggerAsyncId: asyncId of the resource for whose context the async resource was created. It shows the reason behind creating a specific resource.
  • resource: It represents the reference to the async operation releasing during destroy.

All the other callbacks get only one parameter- asyncId.

Before

Whenever an async operation initiates or completes, a callback notifies the user of its status. The before callback is called right before this mentioned callback is executed, and the relevant resource will be assigned with a unique asyncId identifier.

The before callback can be called any times from 0 to n. For instance, when the asynchronous operation gets cancelled, it will be called 0 times, on the other hand, the persistent type resources can call it multiple times.

After

Similar to before, it is called post-execution of the relevant asynchronous resource or right after when the specified callback in before callback finishes its execution.

Destroy

It’s quite easy to guess, isn’t it? Yes, you guessed it right! 

It is called every time the asynchronous resource, corresponding to the unique asyncId, is destroyed regardless of whatever happened to its callback function.

However, in some cases, the resource depend upon the garbage collection for its cleanup which might cause a memory leak in the application, which results in avoid calling destroy. If the resource does not rely upon the garbage, then it won’t be a problem and destroy will do the cleaning.

promiseResolve

This callback is triggered when the Promise gets its resolve function, which is invoked either directly or by some external means to resolve a promise.

Promise Resolve

Use Cases of Async Hooks

Listed below are some major features and use cases of async hooks-

– Promise Execution Tracking

Async hooks play a vital role tracking the lifecycle of promises and their execution, as promises are also asynchronous resources. 

Whenever a new promise is created, the init callback runs. The before and after hooks run pre- and post-completion of a PromiseReactionJob and the resolve hook is called when a promise is resolved.

– Web Request Context Handling

Another major use case of Async Hooks is to store relevant information in context to the request during its lifetime. This feature becomes highly useful to track the user’s behavior in a server.

With async hooks, you can easily store the context data and access it anywhere and anytime in the code.

The process starts with a new request to the server, which initiates calling createRequestContext function to get data to store in a Map. Every async operation initiated as part of this request will be saved in the Map along with the context data (Here init plays an important part). 

Next, destroy keeps the size of the Map under control and do the cleaning. This is how you can get the current execution context by calling getContextData anytime.

– Error Handling with Async Hooks

Whenever an async hook callback throws an error, the application follows the stack trace and exits due to an uncaught exception. Unless you run the application with-abort-on-uncaught-exception, which will print the stack trace exiting the application, the exit callbacks will still be called.

The error handling behavior is due to the fact that all these callbacks run at potentially unstable points, for instance during construction or destruction of a class. This process prevents any unintentional and potential abort to the process by closing it quickly.

– Printing in Async Hooks

Printing is an asynchronous operation and console.log() triggers calling async callbacks. However, using such asynchronous operations inside async callbacks causes infinite recursion. 

For instance, when init runs, the console.log() will trigger another init callback causing endless recursion and increasing stack size.

To avoid this, you should use a synchronous operation like fs.writeFileSync(file, msg, flag) while debugging as it will print to the file without invoking AsyncHooks recursively.

If the logging requires an asynchronous operation, you can track what caused the async operation to initiate using AsyncHooks. As it was logging itself that invoked the AsyncHooks callback, you can skip it which will break the infinite recursion cycle.

– Enhanced Stack Traces

The creator of Node.js, Ryan Dahl, talked about debugging problems in node.js due to event loops, which kills the stack trace. As the async hooks facilitate better tracing of async resources, it allows developers to improve and enrich the stack trace.

Bottom Line

Do you know that you can also measure the duration of an asynchronous operation in real-time? Yes, you can, but by integrating Async hooks module with Performance API module.

Well, this was all about async hooks. I would suggest you to refer to this link if you want to learn more about async hooks.

Thanks for reading!!

Don’t forget to share your response with us in the comment section!

Posted bypayalSeptember 9, 2021September 10, 2021Posted inJavascript, Mobile development, Node JS, React, Web DevelopmentTags: Async hooks, Hooks APIS, JavaScript, NodeJs, Promises, web development

Post navigation


:

Join the Conversation

1 Comment

  1. Jhanvi Mehta says:
    January 13, 2022 at 9:47 am

    Thank you for sharing this amazing article! Becuse I am working on node.js for my project I am regularly read about node.js on the internet and I read your article and that was well written and I learn something New about node.js in your post. Also If you have any tips for node.js then keep sharing with me.

    Reply
Leave a comment

Cancel reply

Your email address will not be published. Required fields are marked *

Leave a comment

Recent Posts

  • Mastering the essence of “Productivity”

    Mastering the essence of “Productivity”

  • Monorepo for React Native Apps with Nx

    Monorepo for React Native Apps with Nx

  • Quick Tips for Software Developers to stay ‘Healthy’

    Quick Tips for Software Developers to stay ‘Healthy’

  • Lean Software Development- How is it Beneficial for Start-ups?

    Lean Software Development- How is it Beneficial for Start-ups?

  • How IoT and Wearables are Improving Fintech in 2022?

    How IoT and Wearables are Improving Fintech in 2022?

  • The Ultimate Guide to Goal Setting Process

    The Ultimate Guide to Goal Setting Process

Talk to our experts now

Have a project or looking for development team? Contact us.

Get a quote

About Us

Habilelabs Private Limited is the ISO 9001:2015 certified IT company, which has marked its flagship in 20+ countries with 100+ projects successfully

Company

  • About
  • Blog
  • Careers
  • Hire Us
  • Privacy Policy

Contact Us

  • +91-9828247415
  • +91-9887992695
  • info@habilelabs.io

Follow Us

Office

  • Habilelabs Private Limited
    4th Floor, I.G.M. School Campus,
    Sec-93 Agarwal Farm, Mansarovar,
    Jaipur, Rajasthan India
    Pin:302020