In this tutorial, you will learn about the differences between Async/Await and Promises when making asynchronous calls in Javascript. When code is asynchronous it simply means that it isn't executed sequentially. In Javascript, asynchronous code may nvovlde calling an API, calling code within a setTimour(), or a setInterval().

When making asynchronous requests using Javascript, you have several options, callbacks, generators (yield) , promises and async and await. When writing async code in Javascript, you should favour one of the newer techniques, unless you have to use an older version of ECMAScript for whatever reason🤞. As callbacks are the old skool way of making async calls, I will omit them in this tutorial. Does this raise a question, out of the approaches which one should you use when writing code?

Async/Await

Async and Await is the latest way that developers can write asynchronous code. Released in ECMAScript 2017, Async and Await is a new syntax that wraps around functions that returns promises. Using async/await is a way to structure your asynchronous code so that it is easier to read. The beauty of async and await is that it makes asynchronous code read like synchronous code. Anything that can make code easier to read for developers will give your project a massive quality boost in terms of readability. This is why you need to know about this stuff, improving quality should be one of your main goals whenever you write code. Below shows how to structure a function so it is asynchronous and take advantage of using async and await:

Let us look at what is going on here:

  • On Line1, the function is decorated with the async keyword.

  • On Line2, the await keyword is used. The await keyword will make the function wait until the promise resolves.

  • On Line3, the promises resolve value is stored in a parameter called result

Async/await functions are known to be non-blocking functions. When await is used, execution of that function call is paused until the promise is resolved. A reference to the call is added to the Javascript queue and the function will not continue and be back into the call stack until something is returned. Putting the keyword async before a function tells the compiler that the function has to return a promise. The benefit of writing code like this is that your asynchronous code can now look and behave like synchronous code. This type of code is a lot easier to read and comprehend compared to code that has lots of nested functions. This is why async and await code is loved by developers. It makes it easier for them to understand what is going on within a codebase.

We now have a frame of reference on how to write asynchronous code using aync and await. I have made a lot of comparisons between writing asynchronous code using promises andasync and await. If you are new to Javascript and do not know what a promise is, let us now look at how promises work.

Promise

The first thing you need to understand around the async and await vs promise debate is that it is mainly about code style. async and await is a sugar-syntax wrapper around a promise. Everything that you can do when writing code that handles asynchronous calls using async and await you can do with a promise instead.

Understanding the philosophy of how a Promise works can be made by comparing how a promise works in real life. A promise is simply a guarantee that something will be done in the future. Just like in real life a promise can only be kept in the future. Historically in Javascript, handling asynchronous code was done using something called a callback function. A callback function would be executed after some asynchronous operation finished executing. Code written using lots of callback functions could be very hard to read. Code that was written within deeply nested callback hell became notorious as areas within a codebase that could contain hidden and unexpected bugs.

Promises were released in 2012 to make developers lives easier 😮‍💨Developers pretty much universally agree that asynchronous code that is written using the promise style syntax is much easier to write compared to writing code using callback functions.

Using a promise makes it easier to track whether an asynchronous event has been executed or not. This is possible through the promise state management. At any given time, a promise can be in one of three states:

Pending: Initial State, before the event has happened. For example, when data is requested from an API, the promise will be in a pending state until the data is returned.

Resolved: After the operation was completed successfully the resolve method is called.

Rejected: If the operation had an error during execution, the promise fails and the rejected method is called.

After a function is called that returns a promise, the promise can be handled in one of two ways. If the promise returns in a resolved state, you can use a function called then() to define what should happen next in the code. If the promise is returned in a rejected state you can use a function called catch() to define what should happen next. To create a promise, you will need to define a Promise object with the correct constructor arguments:

In the code above, if the result of GetState() is true then resolve is called and the promise returns in the resolved state. If GetState() returns false an error is created and the promise is returned in the rejected state. The code to call that promise would be written like this:

In the code above, the then() function is executed when the promise returns in a resolved state and the code in the catch() function is executed when the promise returns in a rejected state.

Another useful thing to note is that a Promise can be chained. If you call a function that returns a promise and that promise returns another promise then the then() functions can be chain together. This type of code would look similar to this:

As long as each calling function returns a promise, this chaining can go on forever 😵‍💫. This promise chaining allows developers to write less code, however, promise chaining can make it harder to understand what the code is doing and follow all the different execution paths.

Async/Await Vs Promise

As long as each calling function returns a promise, this chaining can go on forever 😵‍💫. This promise chaining allows developers to write less code, however, promise chaining can make it harder to understand what the code is doing. This is especially true when you are trying to follow all the different execution paths.

Async/Await Vs Promise

As you can see from the two code examples, there are several differences between promises and async/await:

  • Most developers agree that using async and await results in more concise and easier to reason about code

  • Async and await allows you to wrap your code using a try and catch to handle errors. This can make it easier to manage errors compared to promise rejected chaining and catch()

  • The await keyword only works inside functions decorated with the async keyword. If you try to use await in a normal function the compiler will throw a SyntaxError

  • When writing asynchronous code where the results are reliant on the results from other asynchronous code, code can start to become very hard and confusing to read using a promise, take this example:

When using async and await the same code is much easier to comprehend and reason about:

I personally find it much easier to read the second snippet as it is written sequentially. As long as you use good naming conventions the second argument will read more like a normal sentence. Code that is written in a declarative syntax has been proved to be easier to understand compared to more imperial styled code. Basically, async and await makes it easier for my tiny little brain to understand what is going on 🤯


I am hoping this guide helps you understand the differences between code written using a async and await style compared to code written using a promise based style. At the time of writing, when you need to write async code, use async and await as the developer community in general agrees that this will lead to easier to understand code!

Happy Coding 🤘