DEV Community

Cover image for More ES6 magic: Async/Await
ABailey92
ABailey92

Posted on

More ES6 magic: Async/Await

If you thought promises were the best thing since sliced bread after dealing with callback hell, wait until you discover the JS magic of async and await. It's important to note that you must have a general understanding of how promises work in order to truly understand how to use async and await, since they are just syntactical sugar. So I'll start with giving a brief overview
of promises to get you up to speed if you've never heard of them, or give you a refresher if you already know what they are.

Promises Explained



In the words of MDN

A promise is an object which can be returned synchronously from an asynchronous function.

A Promise constructor takes in a function that takes in two parameters: Reject and Resolve. It will be in one of 3 possible states:

  1. Resolved: A Promise was successful in retrieving data or getting a value
  2. Rejected: A Promise could not retrieve data due to an error or issue
  3. Pending: not yet Resolved or rejected

A .then is then chained to run a function upon success and a .catch is added to provide error handling.

fetch(url)
  .then(process)
  .then(save)
  .catch(handleErrors)
Enter fullscreen mode Exit fullscreen mode

A promise is settled if it’s not pending (it has been resolved or rejected).

How does it get any better than that?

Two words: Async & Await. Well, that's actually three, but I digress.
Let's start with async. The async keyword can be placed before a function like async function test() or const test = async() =>{}. Using the word async before a function means that that function will return a promise. The values returned from that function are automatically wrapped in a resolved promise.
Now onto await! Await can only be used inside of an async function. You can use async without await but you cannot use await without async. Got it? Good. Await tells javascript to wait, to stop what its doing until the promise returned from the async function is rejected or resolved. Let's take a look at difference.

const noAwait = async() =>{
   const {data} = axios.get(url)
console.log(data) // undefined
}
Enter fullscreen mode Exit fullscreen mode

This results in undefined being logged to the console. But why? This is because getting requests take time. As you know javascript is synchronus, so it will continue to move along before that promise is resolved and data is provided a value.

const withAwait = async()=>{
  const {data} = await axios.get(url)
console.log(data) // json object
}
Enter fullscreen mode Exit fullscreen mode

This results in json being logged to the console. This is because the await keyword has been added and tells javascript to wait for the promise to be resolved before it moves on.

You may be thinking: how does error handling work with this syntax? It's very common to use a try and catch block for error handling with async and await.

async function f() {

  try {
    let {data} = await axios('http://no-such-url');
  } catch(err) {
    alert(err); // TypeError: failed to fetch
  }
}

f();
Enter fullscreen mode Exit fullscreen mode

Since async function do return promises you can also just chain a .catch and that will handle a rejected promise as well.

So rather than using promise chaining or the dreaded callback hell nesting, try using async & and await. Together they provide a great framework to write asynchronus code that is easy to read and write.

Top comments (0)