Magical Mystery Guide For Async/Await In Javascript
Tags: javascript
Published: 2019-03-01 09:31:31

---
title: Magical Mystery Guide For Async/Await In Javascript
published: true
tags: javascript 
canonical_url: https://maksimivanov.com/posts/magical-mystery-guide-for-async-await-in-javascript/
---

Hey there! Today we are going to look at **async** and **await** keywords that allow you to pause functions execution, and therefore let you write **asynchronous** code that reads like **synchronous**.

But first let’s go through other ways of dealing with asynchronicity in Javascript. You know, just to make you **appreciate** how async/await allows you to write more readable asynchronous code.

## First We Had Callbacks

Imagine that we have some **MagicalWorldAPI** , and we need to get a list of quests of the hero of some imaginary world.

With callbacks it would look somewhat like this.

```js
getWorld(function(err, world){
  if (err) {
    // handle error;  
    return
  }
  getHero(world.heroId, function(err, hero){
    if (err) {
      //handle error;  
      return
    }
    getQuests(hero.questsIds, function(err, quests){
      if (err) {
        //handle error;  
        return
      }
      console.log(quests);
    }
  });
});
```

Doesn’t look very good, right? A lot of nesting, also you have to handle errors separately in every callback and it’s kinda error prone. You might forget to add a return statement after you’ve handled an error, or do another silly mistake.

Can we improve this?

## Yes, With Promises

Let’s imagine that our **MagicalWorldAPI** was updated and now it returns `Promise` objects. Let’s adapt to it.

```js
getWorld().then(function(world){
  return getHero(world.heroId)
}).then(function(hero){
  return getQuests(hero.questsIds)  
}).then(function(quests){
  console.log(quests)  
}).catch(function(err){
  //handle error
});
```

Now we have a callback in `catch` function where we can handle errors from any part of that chain. Better, but the code is still hard to read. If only we could make it look synchronous…

## Async/Await? Not yet, generators

```js
const co = require('co')

co(function* (){
  var world = yield getWorld();
  var hero = yield getHero(world.heroId);
  var quests = yield getQuests(hero.questsIds);
  console.log(quests);
}).catch(function(err){
  //handle error  
})
```

OK, the part where we use our imaginary **API** looks nice now, but the other code is cryptic! What does that `*` in function declaration do and what are those `yield` statements?

The asterisk after the `function` statement makes it create a **generator function** and the `yield` keyword pauses **generator function** execution and the value of the expression following the `yield` keyword is returned to the generator’s caller.

And `co` is a nice function that can resolve a **generator function** and return a promise.

So in this example, the `getWorld()` returns a promise. Then `yield` pauses further execution of our star signed function and passes the result of `getWorld()` to the `co` function. The `co` function takes the promise, resolves it and passes the value back to the generator function where it is being assigned to the `world` variable.

Then the same is repeated for other variables.

## Finally we are getting to async/await

Let’s rewrite our code once more.

```js
async function(){
  try{
    var world = await getWorld();
    var hero = await getHero(world.heroId);
    var quests = await getQuests(hero.questsIds);
    console.log(quests);
  }
  catch(err){
    //handle error
  }
}
```

Looks familiar, right? We just changed `yield` to `await`, instead of `fuction*` we now have `async function` statement and we don’t use the `co` function here.

Oh, and another thing, we now use the `try/catch` to handle errors. This is good, because we can now handle both synchronous and asynchronous code errors the same way.

**So what happens here?**

The `async function` statement defines an **asynchronous function**. When an **async function** is called, it returns a Promise. When the **async function** returns a value, the `Promise` will be resolved with the returned value. When the **async function** throws an exception, the `Promise` will be rejected.

Also an **async function** can contain an `await` expression, that pauses the execution of the async function and waits for the passed Promise’s resolution, and then resumes the **async function’s** execution and returns the resolved value.

The execution flow will go a lot like in previous example. When we’ll stumble upon the first `await` statement – our **async function** will get paused until the `getWorld()` promise will be resolved. Then **async function** will get unpaused and the resolved value will be assigned to the `world` variable.

Then the same will be repeated for other variables.

## Summary

Today we’ve learned that using `async` statement you can create **asynchronous function**.

Inside that function you can use the `await` statement in front of expression that returns a `Promise`.

When the **async function** will by executed, it will pause just where the `await` statement is until that `Promise` is resolved.

And also we’ve learned that using `async/await` you can simplify reading of an asynchronous code by giving a more synchronous flow to it.