Cleaning Up Asynchronous Code With ES7 Async/Await

Chris Pouliot
2 min readNov 12, 2016

--

Or how my code became way easier to read after replacing promises and callbacks with the new async/await features of ES7.

Replacing Promises

Promises are a great way to perform asynchronous tasks. You describe what you want to happen once the task completes, freeing your app to do other tasks in the meantime.

Here’s an example of a request using promises.

This code is pretty straightforward, but might be confusing to those learning Javascript since execution order isn’t obvious. Between each .then() Javascript’s event loop works on other tasks that need to be executed, and returns to your code once the promise is resolved.

Here’s a great resource to learn more about the Javascript Event Loop

Something new in ES7 is the async and await keywords, which let’s us write asynchronous code in a synchronous style.

Here is the same example using the new keywords.

This code is much easier to read since it uses a synchronous style.

What’s going on there?

The two most important parts are the function declaration

async function loadPosts() {...}

and the use of await

let postData = await request("...")

The await keyword blocks execution until the function you’ve called is completed (which uses promises under the hood), and gives you the result. This will work with any function that returns a promise.

Finally, we need to tell Javascript that we’d like to use await . We do this with the async keyword in the function declaration. This ensures other code can be executed while ours is waiting for a result.

The use of async/await also let’s us catch errors in a synchronous way. We can use a regular try {...} catch(err) {...} statement to catch any errors thrown during the execution of our code, instead of having to rely on the .catch() method on a promise chain.

Mistakes I Made

The following code looks like it will do what we want, but it contains a bug.

The problem is that the code waits on every url before iterating to the next value of the array. To make this faster, we can make all the requests resolve in parallel.

The requests will resolve in the background, letting the loop continue to the next iteration instead of waiting for a result immediately. In this way the code will only take as long as the slowest request, versus executing each request one after another.

How can I start using this now?

Since ES7 is still being defined, you’ll have to use a transpiler/polyfill that will let you use the new features. I’ve been using Babel to achieve this.

Babel will transpile your code into a more widely supported version of Javascript.

> npm install --save-dev babel-cli babel-preset-es2015 babel-preset-stage-3

Here is what my .babelrc file looks like

{
"presets": ["es2015", "stage-3"]
}

I then use babel-node in my package.json to transpile it before execution.

"scripts": {
"start": "babel-node code.js"
}

Resources

Here are some sweet resources to learn more about asynchronous JS and ES7.

The Rise of Async Javascript

What the Heck is the Event Loop Anyway?

Async Programming in ES7

--

--