Async/Await featured image

Recognising the advantages and disadvantages of async/await requires an understanding of callbacks and promises. Before we review these lets first remind ourselves of the problem they solve: Asynchrony.

Javascript is a blocking, synchronous single threaded language. This essentially means it can only perform one operation at a time. Suppose we wanted to execute some long running piece of code e.g. an HTTP request. While we wait for the request to complete we wouldn’t want the users interface to be blocked. This is where callbacks come to the rescue. They allow us to run asynchronous non blocking operations.

Callbacks

The problem that callbacks introduce is called Christmas tree hell/callback hell. Many developers find themselves in this situation after nesting callbacks. For example, once an HTTP request completes we may then nest a callback to update the database. This can quickly get out of control and become very difficult to read and reason about.

Promises to the rescue

A promise is an object which represents an asynchronous task that will complete some time in the future. To complete a promise we call the resolve function. If we encounter an error we can call the reject function. When a promise is called it returns a promise. This means we can chain promises together. Promises try to solve the problems associated with callbacks by splitting up the code. Take a look at the rewritten code below and you’ll notice that it’s now much easier to follow the flow:

Problems with promises

The difficulties with promises arise when we have a chain of promises. What if midway through the chain the user lost internet connection and the request the the database failed? How do we handle the remaining promises in the chain? We have a few options available to handle this situation but for the purpose of this blog we’ll take a look at async/await and how it can help.

Async/Await

Async functions are just syntactic sugar for promises – they use promises under the hood. To declare a function as async we just prepend the declaration with async. To wait for a long running piece of code to complete we use await. Exceptions will bubble up to the parent just like with promises however with async functions we can use the try/catch syntax to catch errors. It’s worth mentioning that any exceptions that our not explicitly caught with a try catch will be swallowed. This applies to both async functions and promise, so be sure to catch all errors in the chain.

Async/await give us the advantage of asynchronous code which looks like synchronous code. Take a look at the async function below. In comparison to the promise based version this is much easier to read and reason about.

Summary

We have briefly reviewed callbacks, promises and async/await and identified the problems they solve along with issues they may introduce. Hopefully the next time you come to write asynchronous code you’ll consider which solution would be best for the situation.

One last thing worth mentioning before we finish up is browser support. At the current time of writing async/await is not supported by all browsers, so you will require a service like Babel to polyfill browser support.