Converting Promises to async/await in JavaScript


Promises were introduced to JavaScript in ES6 (ES2015), which provided a way to deal with asynchronous code without entering what we like to call “callback hell”.

However, they were superseded by async functions in ES2017, which use the Promise API.

Brief Overview

When promises are called, they enter a pending state, during which the caller function continues execution as normal (asynchronous).

While the caller function continues, it is also waiting for the promise to enter either the resolved state or rejected state.

Keep in mind that async/await is built on promises. It just provides a simpler syntax for dealing with asynchronous JavaScript code.

Conversions

Let’s see how the same function can be written with the Promise API and with async/await.

Here, we want to access a JSON object holding movie information, and then grab the first movie in the response.

const getWithPromises = () => {
  return fetch('/movies.json')                       // Get movies list
        .then(resp => resp.json())                   // Parse JSON
        .then(movies => movies[0])                   // Pick first movie
        .then(movie => fetch(`/movies/${movie.id}`)) // Get movie data
        .then(movieResp => movieResp.json());        // Parse JSON
}
getWithPromises();
const getWithAsync = async () => {
  const resp = await fetch('/movies.json');             // Get movies list
  const movies = await resp.json();                     // Parse JSON
  const movie = movies[0];                              // Pick first movie
  const movieResp = await fetch(`/movies/${movie.id}`); // Get movie data
  const movieData = await movieResp.json();             // Parse JSON
  return movieData;
}
getWithAsync();

As you can see, async/await provides a more intuitive syntax since it looks just like normal synchronous code.

With Promises, we must first understand that the generated output of each then() is piped into each subsequent then() method.