118 lines
3.6 KiB
Markdown
118 lines
3.6 KiB
Markdown
---
|
|
title: Await Promises
|
|
---
|
|
## Await Promises
|
|
|
|
The `async` / `await` <a href='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators' target='_blank' rel='nofollow'>operators</a> make it easier to implement many async Promises. They also allow engineers to write clearer, more succinct, testable code.
|
|
|
|
To understand this subject, you should have a solid understanding of how <a href='https://guide.freecodecamp.org/javascript/promises' target='_blank' rel='nofollow'>Promises</a> work.
|
|
|
|
---
|
|
|
|
## Basic Syntax
|
|
|
|
``` javascript
|
|
function slowlyResolvedPromiseFunc(string) {
|
|
return new Promise(resolve => {
|
|
setTimeout(() => {
|
|
resolve(string);
|
|
}, 5000);
|
|
});
|
|
}
|
|
|
|
async function doIt() {
|
|
const myPromise = await slowlyResolvedPromiseFunc("foo");
|
|
console.log(myPromise); // "foo"
|
|
}
|
|
|
|
doIt();
|
|
```
|
|
|
|
There are a few things to note:
|
|
|
|
* The function that encompasses the `await` declaration must include the `async` operator. This will tell the JS interpreter that it must wait until the Promise is resolved or rejected.
|
|
* The `await` operator must be inline, during the const declaration.
|
|
* This works for `reject` as well as `resolve`.
|
|
|
|
---
|
|
|
|
## Nested Promises vs. `Async` / `Await`
|
|
|
|
Implementing a single Promise is pretty straightforward. In contrast, Chained Promises or the creation of a dependency pattern may produce "spaghetti code".
|
|
|
|
The following examples assume that the <a href='https://github.com/request/request-promise' target='_blank' rel='nofollow'>`request-promise`</a> library is available as `rp`.
|
|
|
|
### Chained/Nested Promises
|
|
|
|
``` javascript
|
|
// First Promise
|
|
const fooPromise = rp("http://domain.com/foo");
|
|
|
|
fooPromise.then(resultFoo => {
|
|
// Must wait for "foo" to resolve
|
|
console.log(resultFoo);
|
|
|
|
const barPromise = rp("http://domain.com/bar");
|
|
const bazPromise = rp("http://domain.com/baz");
|
|
|
|
return Promise.all([barPromise, bazPromise]);
|
|
}).then(resultArr => {
|
|
// Handle "bar" and "baz" resolutions here
|
|
console.log(resultArr[0]);
|
|
console.log(resultArr[1]);
|
|
});
|
|
```
|
|
|
|
### `async` and `await` Promises
|
|
|
|
``` javascript
|
|
// Wrap everything in an async function
|
|
async function doItAll() {
|
|
// Grab data from "foo" endpoint, but wait for resolution
|
|
console.log(await rp("http://domain.com/foo"));
|
|
|
|
// Concurrently kick off the next two async calls,
|
|
// don't wait for "bar" to kick off "baz"
|
|
const barPromise = rp("http://domain.com/bar");
|
|
const bazPromise = rp("http://domain.com/baz");
|
|
|
|
// After both are concurrently kicked off, wait for both
|
|
const barResponse = await barPromise;
|
|
const bazResponse = await bazPromise;
|
|
|
|
console.log(barResponse);
|
|
console.log(bazResponse);
|
|
}
|
|
|
|
// Finally, invoke the async function
|
|
doItAll().then(() => console.log('Done!'));
|
|
```
|
|
|
|
The advantages of using `async` and `await` should be clear. This code is more readable, modular, and testable.
|
|
|
|
It's fair to note that even though there is an added sense of concurrency, the underlying computational process is the same as the previous example.
|
|
|
|
---
|
|
|
|
## Handling Errors / Rejection
|
|
|
|
A basic try-catch block handles a rejected Promise.
|
|
|
|
``` javascript
|
|
async function errorExample() {
|
|
try {
|
|
const rejectedPromise = await Promise.reject("Oh-oh!");
|
|
} catch (error) {
|
|
console.log(error); // "Uh-oh!"
|
|
}
|
|
}
|
|
|
|
errorExample();
|
|
```
|
|
|
|
---
|
|
|
|
#### More Information:
|
|
|
|
* `await` Operator <a href='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await' target='_blank' rel='nofollow'>MDN Docs</a>
|
|
* `async` Function Operator <a href='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/async_function' target='_blank' rel='nofollow'>MDN Docs</a> |