Skip to content

Instantly share code, notes, and snippets.

@mlimberg
Last active October 9, 2017 22:00
Show Gist options
  • Save mlimberg/66e2d71386c304ce50771392618c0239 to your computer and use it in GitHub Desktop.
Save mlimberg/66e2d71386c304ce50771392618c0239 to your computer and use it in GitHub Desktop.

Async / Await

Just like we have Promises to add some syntactic sugar to structured callbacks, we now have async functions that come with ES7 to help us write cleaner code when working with promises and asynchronous operations.

A few key points about async functions:
  • The async keyword is required
  • Async functions return a Promise
  • An async function can contain an await expression
    • Using the await expression will pause the execution of the function and await resolution of the specific promise it is called on

Take the following example which compares a bit of a contrived problem using promises vs. async/await.

First assume we have these functions written:

const wait2Seconds = value  => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(value);
    }, 2000);
  });
}

const wait4Seconds = value  => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(value);
    }, 4000);
  });
}

Next we have a function that takes a 3rd value, chains promises to wait until we have the values from the first two timeout functions and returns a promise with all of them added up. Writing this using promises can become overwhelming quickly.

const addStuff = value => {
  const promiseToReturn = wait2Seconds(10)
  .then(val => {
    return val
  })
  .then(val1 => {
    return wait4Seconds(20)
    .then(val2 => {
      return val2 + val1
    })
    .then(sum => {
      return sum + value
    })
  })
  
  return new Promise(res => res(promiseToReturn))
}

Not confusing at all...

Let's see what it looks like using async and await:

const addStuff = async value => {
  const val1 = await wait2Seconds(10)
  const val2 = await wait4Seconds(20)
  
  return value + val1 + val2
}

MUCH more readable :).

But, it matters where we say to await the resolution of a promise. Take the following:

const addStuff = async value => {
  const val1 = wait2Seconds(10)
  const val2 = wait4Seconds(20)
  
  return value + await val1 + await val2
}

Instead of awaiting the first promise, and then the second, this code fires off both and essentially takes as long as the longest timeout. This is more like using Promise.all:

const addStuff = value => {
  const promisesToResolve = [
    wait4Seconds(10),
    wait2Seconds(20)
  ]
  
  return Promise.all(promisesToResolve).then(vals => {
    return value + vals.reduce((acc, val) => acc + val, 0)
  })
}

This example takes only as long as the longest setTimeout because it fires off the wait2Seconds and wait4Seconds back to back. Let's throw some console.logs in our timed functions to see how these differ.

My guess is you're still shaking your head wondering wtf is going on. That's ok!

Check out this article!

Recap

  • What is an async function?
  • Why were they added to the ECMAScript standard?
  • What does an async function return?
  • What does the await keyword do within an async function?

Resources:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment