How to use Javascript ES8 feature: async / await

ECMAScript 2017 (ES8) version introduced a new keyword – async. When put in front of a function, it returns a Promise as a result. There is also a new await keyword that can only be used inside of the async function. This will allow to wait for some the Promise to settle before moving on.

So what problem does async solve since it looks like we can do all of the above just by using Promises or callbacks?

One of the benefits is more clear control flow. It feels as if you reading synchronous code which is much easier to digest. The second benefit is that we can wait on some action to complete. For instance, if a function depends on some data that needs to be fetched first, you can just use await get the data and pass it on. Essentially there’s no need to pass a callback or nest a Promise.then().

So remember whatever the returned result, async wraps it in a Promise.

async function getMeSomeFood() {
  return 'Here\'s your salad'; // returns resolved Promise
}

await can be used inside of an asynchronous operation. As I mentioned earlier, it will pause the execution and wait for a Promise to resolve or fail before moving on to the rest of the code.

async function getMeSomeFood() {
  function prepare() {
    return new Promise(resolve => {     					
      setTimeout(function() {
        resolve('Done');
        console.log('Done preparing!');
      }, 4000);
    });
  };
  
  function serve() {
    return new Promise(resolve => {     					
      setTimeout(function() {
        resolve('Done');
        console.log('Served!');
      }, 2000);
    });
  };

  await prepare(); // waits for the Promise to settle and return
  serve(); // runs straight after prepare() is done
}

getMeSomeFood();

As it can be seen from the above example, we delay prepare() by 4 seconds and serve() by 2. Since we asked JavaScript to wait for the first function to finish before moving on to the second one, “Done preparing!” will be logged before “Served!”.

Nice!

One last point to mention is that error handling inside async functions that use await is usually done by using try...catch block.

try {
  await someAsyncFunction();
} catch(e) {
  // handle error here
}

Key takeaways:

  • An async function returns a promise implicitly
  • await keyword can only be used inside of the async function
  • You should use try...catch to catch any errors