Async JavaScript From Pure Callbacks to Promises to Async-Await

Danstan Onyango
5 min readJun 22, 2019

I first wrote JavaScript after a few months of learning C and its async nature just twisted my head and threw me off the grid most of the time. I struggled to get the code to do what I wanted to do and write quality code. I could spend time debugging complicated callbacks and unhandled promises rejections. You may also have had this experience or just having it So I have decided to draft this reference on async JS to document what I understand and use on a daily basis.

Let’s start from where it all started.

Async Code

JavaScript is Asynchronous, Single threaded and Event-driven. If you want to read more on the JS core features check out my story on Event-driven Programming with Nodejs. Those three features are JS’s main strengths and also its main problems, “Just my opinion”. Assume we have a set of 5 functions that take different times to execute and we want them to execute in the descending order of how long each takes to execute. The first thing to do is to call the one we would like to finish first in the first line and expect our desired result to be:

i was no: 1 and i take 10 seconds
i was no: 2 and i take 8 seconds
i was no: 3 and i take 6 seconds
i was no: 4 and i take 4 seconds
i was no: 5 and i take 1 second
Done

However, when we run the above code, this is what we get:

Done
i was no: 5 and i take 1 second
i was no: 4 and i take 4 seconds
i was no: 3 and i take 6 seconds
i was no: 2 and i take 8 seconds
i was no: 1 and i take 10 seconds

This happens because each of these functions takes different times to finish executing. They have asynchronous tasks in them. The JS runtime schedules them and lets them take the time they want without any blocking the other, which is a very cool feature. Now to get the desired result, the first option we have to use callbacks. We call the first functions and pass the second as a callback to it which it calls when done. We do the same thing with the third to the second and so forth. Let’s see how the code above will look like with callbacks.

Callbacks

Callbacks are functions that are passed to other functions an argument to be executed after some task, routine whatever is being done. The above code written in callbacks flavor would be:

This definitely does the job but hell No! What do you think about the part of the code from lines 37 to 49 🤔🤔🤔? This is what is called Callback Hell in the JS community and we even have a website for it Lol.

Imagine we also doing error handling on this code with some if, else statements! How would the code look like? Well, let me show you how ugly it is.

What do you think?

Look at that!! 😲😲. I mean where do we even start to understand code written like this? Let’s find a solution quickly to replace that X-Mass tree-like structure. We will try promises.

Promises

A Promise is an object representing the eventual completion or failure of an asynchronous operation. Our code looks prettier when “promisified”: i.e we make each of these functions return a promise and chain them.

In this version, each of our functions returns a promise that is chained to the next and so forth. This is much better in my opinion because you can easily see the flow of the code and how pretty it is. Let’s say we wanted to handle errors that may occur in each part of the chain, we just call the catch method returned by the promise chain.

This will “catch” all errors in any of the functions that are part of the promise chain, just as the name suggests. How is the experience so far? What if I told you that we have another better way to make this look better? Well, this is where we were coming to and besides code always gets better every day. Let’s talk async-await .

Async-Await

Async-Await is a recent syntax for avoiding chained promise calls because they also get too long and can potentially lose the flow of your code. The code with async await syntax has the run function marked as async and then all the function-calls in it that return promises are awaited.

You can read more about async await syntax on this link. But so far you have the general idea of how we got to async await. And look at how we can handle errors in an Async-Await model using the old fashioned try/catch

Conclusion

Asynchronous nature of JS makes it very ideal for the clientside but working with async code is and may have been challenging for you as it was for me while starting up. I hope this post helped you have fun and learn something. The entire code is also on GitHub.

Cheers and Let’s keep learning together every day while Staying off Callback Hells.

📝 Read this story later in Journal.

👩‍💻 Wake up every Sunday morning to the week’s most noteworthy stories in Tech waiting in your inbox. Read the Noteworthy in Tech newsletter.

--

--

Danstan Onyango

Software Engineer: Elixir, JavaScript ~ NodeJS- ReactJS, PostgreSQL,MongoDB. Unix Enthusiast. AI, ML and Data Science Aspirations. A believer of Tech.