diff --git a/src/content/resources/javascript/promises/async-await.md b/src/content/resources/javascript/promises/async-await.md index 7f65a7f..292187b 100644 --- a/src/content/resources/javascript/promises/async-await.md +++ b/src/content/resources/javascript/promises/async-await.md @@ -1,53 +1,60 @@ --- authors: - "ddivad#0001" + - "veksen#1060" created_at: "2019/10/01" -title: Async Await +updated_at: 2020/05/20 +title: Async/Await recommended_reading: - 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. ## 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 -async function foo() { - return "foo"; +async function getWeather() { + 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 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 -async function demo() { - let data = await foo(); - console.log(foo); // "foo" +async function checkWeather() { + const weather = await getWeather(); + 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 -async function foo() { - let promise = new Promise((resolve, reject) => { - setTimeout(() => resolve("foo"), 5000); +async function getWeather() { + const promise = new Promise((resolve, reject) => { + setTimeout(() => resolve("sunny"), 5000); }); - let data = await promise; // Execution waits here until promise resolves - console.log(data); // "foo" + const weather = await promise; // Execution waits here until promise resolves + 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). ```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: ```js (async () => { - let data = await foo(); - console.log(data); // "foo" + let weather = await getWeather(); + console.log(weather); // "sunny" })(); ``` @@ -107,6 +114,14 @@ async function getCharacters() { 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 () => { try { 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. - 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. ```js function getCharacters() { return fetch(`https://rickandmortyapi.com/api/character`) - .then((response) => response.json()) - .then((response) => response.results); + .then((res) => res.json()) + .then((res) => res.results); } getCharacters() diff --git a/src/content/resources/javascript/promises/intro.md b/src/content/resources/javascript/promises/intro.md index 9d6df42..9c2c8e6 100644 --- a/src/content/resources/javascript/promises/intro.md +++ b/src/content/resources/javascript/promises/intro.md @@ -1,8 +1,9 @@ --- authors: - "Xetera#0001" + - "veksen#1060" created_at: 2019/07/26 -updated_at: 2019/07/26 +updated_at: 2020/05/20 title: Introduction to Promises recommended_reading: - 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 {} +``` + ## Real World Example Here is a real function that gets character information from the Rick and Morty API.