# How to use async/await in JavaScript

By Atta Ur Rehman Shah (https://attacomsian.com/about). Published May 14, 2019, updated Oct 8, 2022. Topics: JavaScript.
Canonical URL: https://attacomsian.com/blog/async-await-javascript

> A detailed article to learn what is async/await and how to use it in JavaScript to write asynchronous code.

Async/await is a modern way of writing asynchronous functions in JavaScript. They are built on top of [promises](https://attacomsian.com/blog/promises-javascript) and allow us to write asynchronous code synchronously.

## Why Async/await?

Promises are great for writing asynchronous code and have solved the famous [callback hell](https://attacomsian.com/blog/promises-javascript#callback-hell) problem, but they also introduced their own complexities. The code quickly becomes complicated if we chain multiple promises to perform a complex task. 

Async/await was introduced in ES2017 (ES8) to reduce the extra boilerplate code around promises. It drastically improves the code readability and makes it appears synchronous while working asynchronously and non-blocking behind the scene.

## Async Function

To create an async function, all you need to do is add the `async` keyword before the function definition:

```javascript
const sayHi = async () => {
  return 'Hey dev ?'
}
```

The `async` keyword always means one (and just one) thing before any function: **it returns a promise**. Even if it explicitly returns a simple value, like the above, the returned value is automatically enclosed inside a resolved promise. Since the value returned is a promise, we can do something like the below to get the value:

```javascript
sayHi().then(greeting => console.log(greeting)) // Hey dev ?
```

## Await 

The `await` keyword can only be used within an async function. Otherwise, it will throw a syntax error. It waits for a promise to resolve or gets rejected. 

Here is an example:

```javascript
const greet = async () => {
  let message = await sayHi()
  console.log(message)
}

greet() // Hey dev ?
```

Essentially, the `await` keyword makes JavaScript pauses the function execution until the promise is settled and resumes when the result is available. It is better than `promise.then()`  and makes the code easier to understand and write.

## Examples

Here is a quick example of async/await for writing an asynchronous function:

```javascript
const cage = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('?')
    }, 1000)
  })
}

const planet = async () => {
  const bird = await cage()
  console.log('Bird:', bird)
}

planet() // Bird: ? (after 0.5s)
```

In the example above, we first declare a function that returns a new promise that resolves to a value after one second. We then create an async function and wait for the promise to resolve before logging the returned value to the console.

The power of async/await functions becomes more apparent when multiple asynchronous functions are involved:

```javascript
const eagle = () => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('?')
    }, 200)
  })
}

const duck = () => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('?')
    }, 400)
  })
}

const owl = () => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('?')
    }, 600)
  })
}

const planet = async () => {
  const e = await eagle()
  const d = await duck()
  const o = await owl()

  console.log(`Birds: ${e} ${d} ${o}`)
}

planet() // Birds: ? ? ?
```

In the above example, each async function is called sequentially. Every promise is waiting for the promise before (if available) to either resolve or reject before continuing. If you want to execute these promises in parallel, you can simply use [Promise.all()](https://attacomsian.com/blog/promise-all-javascript) to wait until all of them are ready:

```javascript
// ...
const planet = async () => {
  const [e, d, o] = await Promise.all([eagle(), duck(), owl()])

  console.log(`Birds: ${e} ${d} ${o}`)
}

planet() // Birds: ? ? ?
```

## Error Handling

Another benefit of using async/await functions is that both asynchronous and synchronous errors are handled in the same construct, using good old **try...catch** statements. All you need to do is, put your code in a `try` block, and the `catch` block will automatically capture all errors:

```javascript
const isEven = num => {
  return new Promise((resolve, reject) => {
    if (num % 2 == 0) {
      resolve('?')
    } else {
      reject('?')
    }
  })
}

const verify = async num => {
  try {
    const sign = await isEven(num)
    console.log(sign)
  } catch (err) {
    console.log(err)
  }
}

verify(8) // ?
verify(15) // ?
verify('abc') // ?
```

This synchronous error handling doesn't just work for promises, but it also works when there is an actual syntax or runtime error, as you can see above for `verify('abc')`.

Don't want to use `try...catch`? Since the async function returns a promise, you can also use the `catch()` method to deal with unhandled errors:

```javascript
// ...
const verify = async num => {
  const sign = await isEven(num)
  console.log(sign)
}

verify('hey').catch(err => console.log(err)) // ?
```

## Summary

Async/await is a new way of writing asynchronous code in JavaScript. Before this, we used [callbacks](https://attacomsian.com/blog/promises-javascript#what-is-a-callback) and [promises](https://attacomsian.com/blog/promises-javascript#javascript-promises) for asynchronous code. It allows us to write a synchronous-looking code that is easier to maintain and understand.

* Async/await is non-blocking, built on top of promises, and can't be used in plain callbacks.
* The async function always returns a promise.
* The `await` keyword is used to wait for the promise to settle. It can only be used inside an async function.
* A try...catch block can be used to capture both asynchronous and synchronous (syntax, runtime) errors inside an async function.
