Notes on Javascript async and await

MDN has a very good page on async (and await).

Having read them the MDN page plus a bunch of other tutorials, here are my key takeaways:

In general:
  1. async and await are just a nicer syntax for working with promises. So learn promises. Understand promises. And then use async and await to make your promise-using code look nicer.

About async:
  1. Putting async in front of a function definition allows you to use await inside that function.
  2. Putting async in front of a function definition also wraps the function's return value in a promise, if the return value wasn't a promise already. So if my function gets data via a promise and then extracts and transforms the data before returning it, I can just return my transformed data and let async magically re-promise-ify the data for me. :-)
About await:
  1. await lets me use functions that return promises, but write code that looks synchronous, i.e.the code looks as if the function that returns a promise was an old fashion blocking function which returned a normal value.
  2. Not obvious in every tutorial is that... await works on promises, not functions. It doesn't really have anything to do with functions.
  3. await does two things: 1) lets JavaScript do other work until the promise resolves, and 2) unwraps the value which was inside the promise.
  4. You can get a promise from a function and await on it later, to extract the value. This lets you do other stuff before you start awaiting. You can call multiple functions and get multiple promises, and then start awaiting on those promises.
  5. To write a function which will be used with await, just return a promise. That's all. Your function doesn't have to know anything about async/await. It could have been written before async and await existed.
Here are some console games to illustrate a few of the less tutorial-ed points above:

async wraps your function's return value in a promise:
> async function foo() {return 'Foo!'}
> let doo = foo()
> console.log(doo)
>>>> Promise {<resolved>: "Foo!"}

await (waits for and) unwraps promises:
> let goo = await doo
> console.log(goo)
>>>> Foo!

Error handling with async and await:
  1. While await converts a promise into a value, await converts a failing promise into a throw. So you can handle it with try-catch instead of the promise-y way.
  2. At the top level, i.e. not inside an async function so you can't use await,  you can use .catch(...) on the promise returned by an await function.

Comments

Popular posts from this blog

Callback, Promise, Observable, and Doughnuts

Learn grid and grid-template-areas FIRST!!!

The Day TDD Started Working for Me