Promises: The Solution to Callback HELL

Rayan Kazi
5 min readJul 22, 2021
The source for the image is here

Writing callback after callback after callback can be a real pain. You shouldn’t write could that is pretty much nested functions and callbacks; you should be using JavaScript promises. Learn how to use them here.

All the code that will be used in this article can be found here.

What are promises?

The basic idea behind a promise is that its pretty much a promise in real life. In real life, you say “I promise to do something” (In JavaScript it could be promising to get data from an API), and the promise has 2 results; resolved (completed) or rejected (failed).

Creating a new Promise

Creating a new Promise is as simple as creating a variable, and setting it equal to an instance of the promise class. It takes 1 parameter, a function, which takes 2 arguments of “resolve” and “reject”

Inside the function, lets say we want to see if 15 divided by 3 is equal to 5. If it is, we would resolve the promise by calling the resolve function passing in an argument of “Completed”, and if it isn’t, we will reject the promise by calling the reject function passing in an argument of an instance of the error class. The constructor will have the string “Failed”

This promise will always be resolved because 15 divided by 3 is always 5, but if the 3 was changed to a 4, the promise will always be rejected because 15 divided by 4 will never equal 5.

Interacting with Promises

The promise has 2 methods: “then” and “catch”. The then method is used after a promise is resolved (Ex. I made the cookies with chocolate chips, so do…). The then method takes in a function, and that function takes in whatever was returned from the resolved promise.

The catch method is used if an error is found and the promise is rejected. Like the then method, it also takes a function, but the argument in the function is whatever is returned when the promise is rejected.

This is the basics of promises and how to interact with them, but lets see how you can turn an ugly callback into a beautiful promise.

From Callback to Promise

In this example, we will be turning the following callback into a promise.

As we can see, in this case, the callback will log the message “User is studying 📙😊” because both variables are false. If any one them are true, the error callback will be called with varying messages.

The Transformation

So first things first, lets create a new function for the studying promise, and it won’t have any arguments because it isn’t a callback. It will return a new promise.

Next take pretty much all the code inside the callback and put it inside the promise body. Everywhere it calls the error callback, replace it with reject, and when it calls the callback, replace it with resolve.

It is a best practice to reject errors with an instance of the error class, so I will alter the code like this:

The code pretty much looks identical to the callback, so you might be thinking about what the benefits are from using promises, but rest assured promises have many great use cases.

Calling the Promise

Calling the promise is much cleaner in my opinion than calling callbacks; use the then and catch methods to do something with the data returned from the promise.

Now as in the title, promises supposedly are the solution to callback hell; they are. Nested callbacks means indenting and indenting and indenting, and your code becomes extremely messy, and even Prettier can’t even deal with it.

With promises, you can just add as many then methods as you want, and that gets messy much slower than callbacks can.

Using Promises

In this example, we are starting out with 3 promises that all resolve and return a string. They are about playing different video games.

If you wanted to something after all of these promises are resolved, and run all of these promises simultaneously (so that you don’t have to wait for one to finish to run the next), you can use the all method of the Promise class.

The all method takes in an array of all the promises you want to run. Since this returns a promise, you can use the then and catch methods. In the then and catch method, the argument it will take in is an array of messages for each promise (whether it is resolved or rejected).

Note that if 1 promise in the promise all method is rejected, it will directly go to the catch method.

This will log of all of the messages for each promises because all of them resolved.

If you want to do something once one of the promises finish, you can use the promise race method. The race method is just like the all method except it will return as soon as one of the promises are resolved or rejected.

Depending on how fast your machine is, any one of the 3 messages can be logged.

Summary

In general, promises were a great solution to callbacks because they solved so many problems associated with them. Almost all modern day API’s return promises instead of callbacks, so you just learned a valuable skill.

All the code that was written here can be found here.

Thanks for reading 😊! Signing off.

Feel free to reach out to me through my GitHub or email me at rayan.quack.you@gmail.com

--

--

Rayan Kazi

Hello, my name is Rayan. I am a passionate developer who loves to learn and solve problems!