DEV Community

Cover image for Async Patterns in Node.js - Tutorial - Part 5
Abdelhakim mohamed
Abdelhakim mohamed

Posted on

Async Patterns in Node.js - Tutorial - Part 5

Async Patterns in Node.js

Node.js operates on a single-threaded event-driven architecture, meaning that it can handle many operations concurrently without blocking the main thread. This is crucial for creating scalable applications where tasks like I/O operations (reading files, querying databases, etc.) need to happen asynchronously to avoid blocking the execution of other code.

Writing Async vs Sync Code

Synchronous Code

Synchronous code executes one step at a time, meaning each step has to complete before moving to the next. This can block the main thread if operations are slow (e.g., reading a large file or querying a database).

Example (Synchronous Code):

const fs = require('fs');

const data = fs.readFileSync('file.txt', 'utf8');
console.log(data);
Enter fullscreen mode Exit fullscreen mode
  • Problem: If readFileSync takes a long time (e.g., the file is large), the entire application will be blocked during this period.

Asynchronous Code

Asynchronous code, on the other hand, does not block the main thread. Instead of waiting for an operation to complete, the program continues executing and handles the result of the async operation when it's ready.

Example (Asynchronous Code):

const fs = require('fs');
// Call Back
fs.readFile('file.txt', 'utf8', (err, data) => {
  if (err) throw err;
  console.log(data);
});

console.log('This will log before the file content!');
Enter fullscreen mode Exit fullscreen mode
  • In this example, the file is read asynchronously, and the program doesn't block; the line console.log('This will log before the file content!') executes while the file is still being read.

When to Use Synchronous vs Asynchronous

  • Synchronous code is fine for small tasks or scripts where performance is not a concern.
  • Asynchronous code is ideal for I/O-heavy applications like web servers, where you don’t want to block the main thread while waiting for operations like database queries or HTTP requests.

Async/Await

Introduced in ES2017 (Node.js 7.6+), async/await is syntactic sugar built on top of promises. It allows asynchronous code to be written in a synchronous-like fashion, making it more readable and easier to maintain.

Example (Async/Await):

   const fs = require('fs').promises;

   async function readFile() {
     try {
       const data = await fs.readFile('file.txt', 'utf8');
       console.log(data);
     } catch (err) {
       console.error(err);
     }
   }

   readFile();
Enter fullscreen mode Exit fullscreen mode

Summary

  • Callbacks are simple but can lead to callback hell.
  • Promises clean up callback hell and provide better error handling.
  • Async/Await makes asynchronous code look synchronous, improving readability.

Choosing async vs sync code depends on your use case. For I/O-heavy operations, always prefer asynchronous patterns to keep the main thread non-blocking and your application responsive.

Thank you for reading, and happy coding! 🎉

Top comments (0)