How to avoid infinite nesting callbacks

Performing an operation after an asynchronous call has ended requires you to place subsequent program logic inside a callback. Performing multiple steps leads to deeply nested callbacks.

Is there any way to avoid deeply nested callbacks?

There's one good way to flatten nested callbacks. It's got to do with Promise resolving to a value, and it uses async functions and the await keyword. This method allows you to write flat program code free of nested callbacks.

Placing logic inside callback

When using callbacks, you're required to put dependent program logic that is to be executed after an asynchronous operation has completed inside a callback. When you combine multiple such calls, you end up with deeply nested code.

Deeply nested callbacks in JavaScript code.
Deeply nested callbacks in JavaScript code.
Source: http://slides.com/michaelholroyd/asyncnodejs

Let's write a program that reads two files and prints their lengths. When using callbacks, our example looks like the following.

1 var fs = require('fs');
2 
3 fs.readFile('file1.txt', 'utf8', (err, file1) => {
4     fs.readFile('file2.txt', 'utf8', (err, file2) => {
5         console.log(`total length: ${file1.length + file2.length}`);
6     });
7 });

await

Promises and the await keyword can be used to write flat asynchronous code. You need a Promises-based version of your API.

The example Promises, async functions, and await would look like the following. Notice how flat the program structure is - there are no callbacks.

1 var fs = require('fs-promise');
2 
3 (async function() {
4     var file1 = await fs.readFile('file1.txt', 'utf8');
5     var file2 = await fs.readFile('file2.txt', 'utf8');
6 
7     console.log(`total length: ${file1.length + file2.length}`);
8 })();

You can use async functions and the await keyword natively in new JS engines that support it or use TypeScript or Babel to convert code into the previous specifications of JavaScript.

Avoid infinite nesting callbacks

Use ES2017 async functions and await to write flat asynchronous code instead of infinite nesting callbacks. You can use await natively or with the help of TypeScript or Babel.

Related articles

Node doesn't wait for your database call to finish?

Node doesn't wait for your database call to finish?

Learn how asynchronous calls work and make your app run as you intended. Get short email course on asynchronicity and two chapters from Finish Your Node App.

Take Free Course