Callback Hell in Javascript

Callback Hell in Javascript

More commonly known as the Pyramid of Doom, Callback hell is basically an off-pattern seen in the code, particularly while asynchronous programming. It can also be generalized as slang using hazardous numbers of “if” statements. Once your projects become complex and their requirements grow, you can expect yourself to pile under a considerable number of callbacks and that is the initiation to Callback Hell!

Callback Hell in Javascript

Let’s assume a Callback to be any function “X” which is then passed as a parameter to some other function “Y”. So, by definition function ‘Y’ will execute code ‘X’ but can be called in two different ways, i.e. synchronous callback, which is an immediate callback or asynchronous callback, which occurs later on.

So, it is quite evident that the presence of callbacks in the code makes it harder to maintain or further write the code. It poses a hurdle in understanding the flow of code and is a major drawback when debugging the entire code. All the above-mentioned hurdles get worse as we continue to nest more and more callbacks. And this eventually is referred to as the Callback Hell.

So, let’s first proceed to read about synchronous and asynchronous programming in Javascript to get more clarity on Callbacks and Callback hell.

Synchronous Programming

This type of programming can also be understood as a Blocking Code operation as Synchronous programming is a type of programming that allows users to focus on one task at a time and move to the next when the first is successful. Synchronous programming is used very often in daily life programming and makes it simpler to process the code.

Asynchronous Programming

Asynchronous Programming works exactly opposite to the way Synchronous programming works. It allows users to work on their code without hampering or blocking the main thread. It works on parallelization wherein you can perform different tasks kind of simultaneously and can even proceed to the further tasks before even finishing the last one.

An example of asynchronous programming is the setTimeout function. This function takes two arguments. First argument  is the code we wish to execute and the second argument is an integer stating the number of milliseconds to wait before running the code in the first argument. So, the code inside the first argument in this function is put on hold till the timer goes off. This is often called a Non-Blocking behaviour.

There are two patterns in Javascript to deal with the drawbacks of asynchronous programming-

  • Promises (which are built over callbacks internally)
  • Async – await (which are built on top of promises)

Ways to handle Nested Callbacks or Callback Hell

There are a few ways to handle the trouble of Nested Callbacks. One can always use the traditional approach of Promises which will be discussed in detail below. Users can also use async-await which is another feature or they can simply shorten the code by splitting it into various smaller functions.


After every callback is generated, we must generate a promise so that the callbacks can be converted to promises, it makes resolving the callbacks easier as, if the callback is successful, then only we resolve the promise, or else if the callback fails, we can simply reject the promise.

In layman’s terms, Promises are alternatives to Callbacks when it comes to asynchronous programming. So, the purpose of using Promises instead of Callbacks is that Promises are much more readable than callbacks and have many additional benefits and functions. Functions like Fetch and operations in Mongoose can be performed with promises.

Now, to understand Promises a little more, let’s mention their four major states:

  • Fulfilled- it is a state where the actions are successful
  • Pending- where the action hasn’t been fulfilled nor been rejected
  • Rejected-  The action related to the promise failed
  • Settled- The action has either been rejected or failed


So to use the Async feature of converting callbacks or programs to promises, just simply add a async before a normal function and it is a promise now. Async/await is often termed as a syntactical sugar of promises and what it actually means is that this approach helps you avoid the piling up or chaining of then() methods. Note that async also uses chaining internally to handle callbacks but it poses no complications to the code.

Await helps its users write an asynchronous program in the form of a synchronous one, the one that is executed in order. What Await does is that it stops further execution until the previous promise is successfully resolved.


In this blog, we have thoroughly looked at the definition of Callback and how Callback Hells can be managed in Javascript. We also proceeded to discuss Nested Callbacks along with Promises and Async/await functions.

If you ask me about my personal preference, I like the async/await approach the most when handling Nested Callbacks but sometimes the traditional Promises approach works fine too.

Finally, thank you for sparing your precious time to read this post. We hope it provides you with the needed knowledge and guidance.

To know more about Javascript and its functionalities, jump into the coding world of Codedamn and you won’t be disappointed.

Become The Best JavaScript Developer 🚀
Codedamn is the best place to become a proficient developer. Get access to hunderes of practice JavaScript courses, labs, and become employable full-stack JavaScript web developer.

Free money-back guarantee

Unlimited access to all platform courses

100's of practice projects included

ChatGPT Based Instant AI Help

Structured Full-Stack Web Developer Roadmap To Get A Job

Exclusive community for events, workshops

Start Learning

Sharing is caring

Did you like what Vishnupriya wrote? Thank them for their work by sharing it on social media.