mirror of
https://github.com/Stone-Red-Code/website.git
synced 2026-09-07 16:06:12 +02:00
Merge pull request #259 from the-programmers-hangout/content-resources-javascript-promises
content(resources): update/tweak JS promises resources
This commit is contained in:
@@ -1,53 +1,60 @@
|
|||||||
---
|
---
|
||||||
authors:
|
authors:
|
||||||
- "ddivad#0001"
|
- "ddivad#0001"
|
||||||
|
- "veksen#1060"
|
||||||
created_at: "2019/10/01"
|
created_at: "2019/10/01"
|
||||||
title: Async Await
|
updated_at: 2020/05/20
|
||||||
|
title: Async/Await
|
||||||
recommended_reading:
|
recommended_reading:
|
||||||
- javascript/promises/intro
|
- javascript/promises/intro
|
||||||
---
|
---
|
||||||
|
|
||||||
## Async Await
|
## Async/Await
|
||||||
|
|
||||||
Async / Await is another way to handle the calling of asynchronous code and is built on top of Promises. It is a nice and clean way to handle asynchronous code, without the need to `.then()` functions to the promise.
|
Async/Await is another way to handle the calling of asynchronous code and is built on top of Promises. It makes it possible to write asynchronous code that feels synchronous.
|
||||||
|
|
||||||
|
**Its usage is equivalent to resolving a promise with `.then()`**.
|
||||||
|
|
||||||
It is made up of 2 keywords as the name suggests: `async` and `await`. These need to be used together for this method to work.
|
It is made up of 2 keywords as the name suggests: `async` and `await`. These need to be used together for this method to work.
|
||||||
|
|
||||||
## Async
|
## Async
|
||||||
|
|
||||||
The `async` keyword is used to show that the function is going to return a promise. Any return values from the function will be converted to a promise automatically, if they are not already.
|
The `async` keyword is used to show that the function is going to return a promise. **Any return values from the function will be converted to a promise automatically**, if they are not already.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
async function foo() {
|
async function getWeather() {
|
||||||
return "foo";
|
return "sunny";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPromise();
|
||||||
|
// Promise<"sunny">
|
||||||
```
|
```
|
||||||
|
|
||||||
This basic example will return a promise with the value of `foo`.
|
This basic example will return a promise with the value of `getWeather`.
|
||||||
|
|
||||||
## Await
|
## Await
|
||||||
|
|
||||||
The `await` keyword is used to wait until a promise has executed and fetches the result. In order to use the `await` keyword, you **need** to be inside an `async` function.
|
The `await` keyword is used to wait until a promise has executed and fetches the result. In order to use the `await` keyword, you **need** to be inside an `async` function.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
async function demo() {
|
async function checkWeather() {
|
||||||
let data = await foo();
|
const weather = await getWeather();
|
||||||
console.log(foo); // "foo"
|
console.log(weather); // "sunny"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
This code will call the `foo()` function from above and will wait on that line until the promise returned from the `async` function has returned.
|
This code will call the `getWeather()` function from above and will wait on that line until the promise returned from the `async` function has returned.
|
||||||
|
|
||||||
Another example to demonstrate this is if we extended the `foo()` function from above to add a 5 second delay.
|
Another example to demonstrate this is if we extended the `getWeather()` function from above to add a 5 second delay.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
async function foo() {
|
async function getWeather() {
|
||||||
let promise = new Promise((resolve, reject) => {
|
const promise = new Promise((resolve, reject) => {
|
||||||
setTimeout(() => resolve("foo"), 5000);
|
setTimeout(() => resolve("sunny"), 5000);
|
||||||
});
|
});
|
||||||
|
|
||||||
let data = await promise; // Execution waits here until promise resolves
|
const weather = await promise; // Execution waits here until promise resolves
|
||||||
console.log(data); // "foo"
|
console.log(weather); // "sunny"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -81,15 +88,15 @@ As mentioned in the [intro](./intro.md), Promises are the highest source of conf
|
|||||||
`await` will **only** work if the function you try to add `await` to is `async`. Using `await` in top level code will not work (yet).
|
`await` will **only** work if the function you try to add `await` to is `async`. Using `await` in top level code will not work (yet).
|
||||||
|
|
||||||
```js
|
```js
|
||||||
let data = await foo(); // syntax error
|
let weather = await getWeather(); // syntax error
|
||||||
```
|
```
|
||||||
|
|
||||||
To get around this issue, you can use an declare asynchronous function anonymously, if needed:
|
To get around this issue, you can use an declare asynchronous function anonymously, if needed:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
(async () => {
|
(async () => {
|
||||||
let data = await foo();
|
let weather = await getWeather();
|
||||||
console.log(data); // "foo"
|
console.log(weather); // "sunny"
|
||||||
})();
|
})();
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -107,6 +114,14 @@ async function getCharacters() {
|
|||||||
return data.results;
|
return data.results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// or, mixed
|
||||||
|
async function getCharacters() {
|
||||||
|
const data = await fetch(
|
||||||
|
`https://rickandmortyapi.com/api/character`
|
||||||
|
).then((res) => res.json());
|
||||||
|
return data.results;
|
||||||
|
}
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
let characters = await getCharacters();
|
let characters = await getCharacters();
|
||||||
@@ -123,15 +138,28 @@ In this example, we are querying real data from the Rick & Morty API. This API h
|
|||||||
- When we get the result, we need to get the `JSON` value of the data. To do this, the `.json()` method from fetch is used. We then return the results.
|
- When we get the result, we need to get the `JSON` value of the data. To do this, the `.json()` method from fetch is used. We then return the results.
|
||||||
- As `await` can only be used in an `async` function, we use the method from above to make this work. As `getCharacters()` returns a Promise due to it being `async`, we `await` the result. We surround this in a `try...catch` in case fetch returns an error. Then, if no error is returned, `characters` contains the information we want, and is logged to the console. If `getCharacters()` returns an error, that error is also logged.
|
- As `await` can only be used in an `async` function, we use the method from above to make this work. As `getCharacters()` returns a Promise due to it being `async`, we `await` the result. We surround this in a `try...catch` in case fetch returns an error. Then, if no error is returned, `characters` contains the information we want, and is logged to the console. If `getCharacters()` returns an error, that error is also logged.
|
||||||
|
|
||||||
## Comparision with default Promises:
|
### Let's also look at an example from Discord.js:
|
||||||
|
|
||||||
|
```js
|
||||||
|
client.on("message", (msg) => {
|
||||||
|
if (msg.author.bot) return;
|
||||||
|
|
||||||
|
if (msg.content === "ping") {
|
||||||
|
const message = await msg.channel.send("pong");
|
||||||
|
message.react("⚠️");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Comparision with default Promises
|
||||||
|
|
||||||
Below is the same code implemented without using Async / Await as a comparision. Here, you can see the differences between the two methods, and how Aysnc / Await makes the code appear in a _more synchronous_ pattern, and can be clearer to follow.
|
Below is the same code implemented without using Async / Await as a comparision. Here, you can see the differences between the two methods, and how Aysnc / Await makes the code appear in a _more synchronous_ pattern, and can be clearer to follow.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
function getCharacters() {
|
function getCharacters() {
|
||||||
return fetch(`https://rickandmortyapi.com/api/character`)
|
return fetch(`https://rickandmortyapi.com/api/character`)
|
||||||
.then((response) => response.json())
|
.then((res) => res.json())
|
||||||
.then((response) => response.results);
|
.then((res) => res.results);
|
||||||
}
|
}
|
||||||
|
|
||||||
getCharacters()
|
getCharacters()
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
---
|
---
|
||||||
authors:
|
authors:
|
||||||
- "Xetera#0001"
|
- "Xetera#0001"
|
||||||
|
- "veksen#1060"
|
||||||
created_at: 2019/07/26
|
created_at: 2019/07/26
|
||||||
updated_at: 2019/07/26
|
updated_at: 2020/05/20
|
||||||
title: Introduction to Promises
|
title: Introduction to Promises
|
||||||
recommended_reading:
|
recommended_reading:
|
||||||
- javascript/callbacks/intro
|
- javascript/callbacks/intro
|
||||||
@@ -85,6 +86,14 @@ getWeather("Los Angeles").then((weather) => {
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Outlining this one again, because it's very common, is to attempt to use the value of a promise, but not resolving it:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// Incorrect code, don't copy!
|
||||||
|
const weather = getWeather("Los Angeles");
|
||||||
|
console.log(weather); // Promise {<pending>}
|
||||||
|
```
|
||||||
|
|
||||||
## Real World Example
|
## Real World Example
|
||||||
|
|
||||||
Here is a real function that gets character information from the Rick and Morty API.
|
Here is a real function that gets character information from the Rick and Morty API.
|
||||||
|
|||||||
Reference in New Issue
Block a user