by Tiago Lopes Ferreira
Oh yes! Async / Await
Here is a quick reminder of how to write and use a promise.
A Promise represents a value that will be available now, in the future, or (possibly) never.
A Promise state can be one of the following:
- pending — the Promise was neither resolved nor rejected. It represents a Promise‘s initial state.
- resolved — the operation, wrapped by the Promise, completed successfully.
- rejected — the operation failed.
getRandomWithPromise() defines a Promise that resolves with a random number value.
setTimeout() simulates a delay to an asynchronous task such as an HTTP request.
Here’s an example of how we can use
async/await is a keyword+operator pair that simplifies asynchronous code.
- async declares the function is asynchronous.
- await is the operator used to wait for a promise to be fulfilled. It can only be used within an async function.
Let’s build an example, using the
getRandomWithAsync() function and async/await.
The first thing to notice is the keyword async declares the function is asynchronous
The await operator pauses
getRandomWithPromise()until the promise is fulfilled.
When fulfilled the promise can be:
resolved — meaning that await will return the resolved value.
rejected — meaning that await will throw the rejected value.
Because a promise can throw an unexpected error it is important to wrap our code inside a try/catch block.
Note that the body of
getRandomWithAsync() reads like it’s a synchronous function. This is one of the advantages of async/await. It makes the code logic easy to follow, even though it’s doing complicated work.
There’s no longer the need for indentation as with a promise chain.
It’s important to remember await can only be used inside an async function. Otherwise, you’ll get a syntax error.
This is how to use await with an Immediately Invoked Function Expression (IIFE).
We can also create async functions inside classes.
What if we have more than one promise to fulfill before continuing?
We can do it in two ways — sequentially or concurrently.
Promise b is only executed after Promise a fulfills. So the function execution time is the sum of execution time for Promises a and b.
This can be a major performance issue. The good news is we can run both promises concurrently to save time.
We can run both promises in parallel by modifying the code. If you request the random numbers and save the promises, they will run concurrently. We wait for both promises to complete by using await in separate expressions. The result is displayed when they are both complete
The function execution time is equal to the promise that takes the longest time.
Concurrently (with Promise.all)
We can also use
Promise.all for concurrency.
One of the advantages is that
Promise.all has fail-fast behavior. If one promise fails, Promise.all will not wait for the other promises to be fulfilled. It rejects immediately.
await and thenable
The use of the await operator is not restricted to promises. await will convert any non-promise value into a promise value. It does it by wrapping the value into
await can be used with any object that has a
.then() method. This object is also known as a thenable.
async is the keyword that specifies that a function is asynchronous.
await is the operator used to wait for a promise to be fulfilled.
The syntax async/await makes asynchronous code look like synchronous code. This makes the code easier to read and understand.
Remember that promises can generate unexpected errors. It’s important to wrap the code inside a try/catch block to handle them.
You can handle multiple promises in two ways: sequential or concurrent. Concurrency has the advantage because promises can run in parallel.
Finally, the operator await is not restricted to promises. We can use it with any object with a
.then() method (i.e. a thenable).
Thanks to 🍻
- Brian Terlson for his Async Functions Proposition
- MDN — async function
- To all Adventure Time fans
Be sure to check out my articles on ES6
Demystifying ES6 Iterables & Iterators
Generators, aka, an implementation of iterables.medium.freecodecamp.org