Learn Async Await From Four Examples

Share:
Source Code

The goal of this tutorial is to show you how you can use the async/await feature from the newest version of Javascript.  I will explain quickly and painlessly how you can replace Promises with async/await, do proper error handling, and discuss simple synchronous and parallel async await techniques.

Be sure to use the latest version of nodejs (version >7.6.0) as it supports async/await out the of box, but if you can’t use the latest node, you can use BabelJS to transpile your code to ES6 equivalent.

To start things off, we’ll be using two promise based functions as our asynchronous call examples:

function getPentaCodeAvatar() {
  return new Promise((resolve, reject) => {
    github.search.users({ q: 'pentacode' }, (err, res) => {
      if (err) {
        reject(err);
        return;
      }
      let avatarUrl = '';
      if (res.data && res.data.items) {
        avatarUrl = res.data.items[0].avatar_url;
      }
      resolve(avatarUrl);
    });
  })
}

function getReactAvatar() {
  return new Promise((resolve, reject) => {
    github.search.users({ q: 'react' }, (err, res) => {
      if (err) {
        reject(err);
        return;
      }
      let avatarUrl = '';
      if (res.data && res.data.items) {
        avatarUrl = res.data.items[0].avatar_url;
      }
      resolve(avatarUrl);
    });
  })
}

These are very basic promised based functions that utilizes Github’s NPM package to get user’s avatar from Github’s server.

Replace Promises with Async Await

To call the above functions with Promises, we would do:

getPentaCodeAvatar()
  .then((result) => {
    console.log(result);
  })
  .catch((e) => {
    console.error('Error in getPentaCodeAvatarFunction (Promise Based)', e);
  });

The syntax is clean and simple, definitely better than nested callbacks.  The error is caught in the .catch() function. The thing that bothers me are the multiple anonymous functions passed in to .then() and .catch(), still not as clean as I would like.

Let’s see how we can do this with async/await:

async function start() {
  const avatarUrl = await getPentaCodeAvatar();
  console.log(avatarUrl);
}

start();

What is this magic? This code looks synchronous you say, well that is the intent, we first proceed the word function with the keyword async, this will tell the compiler that the following function makes use of asynchronous calls to something, then we add the keyword await in front of the promise function getPentaCodeAvatar(), this will make the function wait until the asynchronous code within getPentaCodeAvatar() to finish before setting the result of that to the avatarUrl variable.  Please keep in mind that you can only use the keyword await within a function that has been marked async, otherwise you’ll get a syntax error from node.

Error Handling

With Promises, you can catch errors with the .catch() function, but how do you do it with Async/Await?  The answer is try…catch, you simply wrap the code within a try…catch and errors will be caught:

async function start() {
  try {
    const avatarUrl = await getPentaCodeAvatar();
    console.log(avatarUrl);
  } catch (e) {
    console.error('Error in getPentaCodeAvatarFunction (Async Await Based)', e);
  }
}

start();

The good thing about this is that you’ll be able to catch errors from within the promise function AND anything within the try block, like a JSON.parse error.  IMO this is far more powerful and familiar to the average developer, the downside of that is you would have to write a lot of try/catches.

Synchronous

Let’s say you need to call two or three asynchronous functions and need results from previous calls in order to perform the next one, in other words, synchronous calls, then the following example will show you how to do that:

async function startSynchronous() {
  try {
    const pentaCodeAvatarUrl = await getPentaCodeAvatar();
    const reactAvatarUrl = await getReactAvatar();
    const totalURL = pentaCodeAvatarUrl + reactAvatarUrl;
    console.log(totalURL);
  } catch (e) {
    console.error('Error in startSynchronous (Async Await Based)', e);
  }
}

startSynchronous();

This looks eerily like a normal function calls and assignment, you call getPentaCodeAvatar() and get the result value stored in a variable, then you call getReactAvatar() and store the result in that in another variable, and finally you combine them together in another variable.  async/await makes this easy to understand and painlessly allow you to manipulate variables from different async functions.

Parallel

What about if you want a set of asynchronous functions to run all at the same time in parallel?

async function startParallel() {
  try {
    let [ pentaCodeAvatarUrl, reactAvatarUrl ] = await Promise.all([getPentaCodeAvatar(), getReactAvatar()]);
    console.log(pentaCodeAvatarUrl, reactAvatarUrl)
  } catch (e) {
    console.error('Error in startParallel (Async Await Based)', e);
  }
}

startParallel();

That’s right, you can can wrap them in a Promise.all and use the keyword await in front of it.  This is POWERFUL, because it combines the power of async/await and Promises to perform what we want, and in the process make the code very simple to understand.

I hope these four examples explained the power of async/await, and hopefully you can start to incorporate them into your projects.

Comments Or Questions? Discuss In Our Discord

If you enjoyed this tutorial, make sure to subscribe to our Youtube Channel and follow us on Twitter @pentacodevids for latest updates!

More from PentaCode