Avoiding Callback hell in Node js

Jay B
3 min readMar 3, 2020

--

For most of the time, developers had to rely on callbacks for working with asynchronous JS code. As a result, many of the developers have experienced callback hell and the horror one goes through when faced with functions looking like this.

To avoid this hell we have promises which came in as a new feature in ES6. Promises offer a much more organized alternative to callbacks and most of the developers quickly moved on to using them instead of using callbacks.

And now with the addition of Async/Await, writing JavaScript code has got even better.

What is Async-Await

One of the best things to come out in Node.js is the async-await feature. Async await makes asynchronous javascript code look like it’s synchronous. When an async function is called, it returns a Promise. When the async function returns a value, the Promise will be resolved with the returned value. When the async function throws an exception or some value, the Promise will be rejected with the thrown value.

Async - declares an asynchronous function

The Async function can contain one or many operations like e.g requesting particular data from the database or posting any request data to the database. All these operations may require variable time to complete. As the javascript has asynchronous nature, it will not wait for the first operation to be completed, it may move to the second operation and so on. To make the function run synchronously we need to make the operations, await.

Await - pauses the execution of async functions

The await expression causes async function execution to pause until a Promise is resolved or rejected to resume execution of the async function after resolved. When resumed, the value of the await expression is that of the resolved Promise. In the async function, there can be multiple operations, to run them synchronously i.e one after the other we need to apply await expression on each of them.

This may come handy when we need to perform some database operations where the second operation is reliant on the first one.

In the example above, we fetch a user, once you have the User object, declare it as the constant User, then we fetch a member with the User, if it's there, it'll get a role, add the role to the member, and send a message to the channel.

If anyone of the promises fails, the code will stop executing the rest of the operations inside the try block and will run the block inside catch, with the Error object, and will send an error to the console.

--

--