Merge pull request #1666 from jchue/patch-8

Make minor grammar corrections/updates to async/async-await
This commit is contained in:
Peter Roche 2020-01-02 14:41:24 -07:00 committed by GitHub
commit 14e4e9f96b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -14,7 +14,7 @@ async function f() {
The word "async" before a function means one simple thing: a function always returns a promise. Other values are wrapped in a resolved promise automatically. The word "async" before a function means one simple thing: a function always returns a promise. Other values are wrapped in a resolved promise automatically.
For instance, this function returns a resolved promise with the result of `1`, let's test it: For instance, this function returns a resolved promise with the result of `1`; let's test it:
```js run ```js run
async function f() { async function f() {
@ -24,7 +24,7 @@ async function f() {
f().then(alert); // 1 f().then(alert); // 1
``` ```
...We could explicitly return a promise, that would be the same: ...We could explicitly return a promise, which would be the same:
```js run ```js run
async function f() { async function f() {
@ -67,7 +67,7 @@ f();
The function execution "pauses" at the line `(*)` and resumes when the promise settles, with `result` becoming its result. So the code above shows "done!" in one second. The function execution "pauses" at the line `(*)` and resumes when the promise settles, with `result` becoming its result. So the code above shows "done!" in one second.
Let's emphasize: `await` literally makes JavaScript wait until the promise settles, and then go on with the result. That doesn't cost any CPU resources, because the engine can do other jobs meanwhile: execute other scripts, handle events etc. Let's emphasize: `await` literally makes JavaScript wait until the promise settles, and then go on with the result. That doesn't cost any CPU resources, because the engine can do other jobs in the meantime: execute other scripts, handle events, etc.
It's just a more elegant syntax of getting the promise result than `promise.then`, easier to read and write. It's just a more elegant syntax of getting the promise result than `promise.then`, easier to read and write.
@ -130,7 +130,7 @@ let response = await fetch('/article/promise-chaining/user.json');
let user = await response.json(); let user = await response.json();
``` ```
We can wrap it into an anonymous async function, like this: But we can wrap it into an anonymous async function, like this:
```js ```js
(async () => { (async () => {
@ -143,9 +143,9 @@ We can wrap it into an anonymous async function, like this:
```` ````
````smart header="`await` accepts \"thenables\"" ````smart header="`await` accepts \"thenables\""
Like `promise.then`, `await` allows to use thenable objects (those with a callable `then` method). The idea is that a 3rd-party object may not be a promise, but promise-compatible: if it supports `.then`, that's enough to use with `await`. Like `promise.then`, `await` allows to use thenable objects (those with a callable `then` method). The idea is that a third-party object may not be a promise, but promise-compatible: if it supports `.then`, that's enough to use with `await`.
Here's a demo `Thenable` class, the `await` below accepts its instances: Here's a demo `Thenable` class; the `await` below accepts its instances:
```js run ```js run
class Thenable { class Thenable {
@ -168,7 +168,7 @@ async function f() {
f(); f();
``` ```
If `await` gets a non-promise object with `.then`, it calls that method providing built-in functions `resolve`, `reject` as arguments (just as it does for a regular `Promise` executor). Then `await` waits until one of them is called (in the example above it happens in the line `(*)`) and then proceeds with the result. If `await` gets a non-promise object with `.then`, it calls that method providing the built-in functions `resolve` and `reject` as arguments (just as it does for a regular `Promise` executor). Then `await` waits until one of them is called (in the example above it happens in the line `(*)`) and then proceeds with the result.
```` ````
````smart header="Async class methods" ````smart header="Async class methods"
@ -192,7 +192,7 @@ The meaning is the same: it ensures that the returned value is a promise and ena
```` ````
## Error handling ## Error handling
If a promise resolves normally, then `await promise` returns the result. But in case of a rejection, it throws the error, just as if there were a `throw` statement at that line. If a promise resolves normally, then `await promise` returns the result. But in the case of a rejection, it throws the error, just as if there were a `throw` statement at that line.
This code: This code:
@ -204,7 +204,7 @@ async function f() {
} }
``` ```
...Is the same as this: ...is the same as this:
```js ```js
async function f() { async function f() {
@ -233,7 +233,7 @@ async function f() {
f(); f();
``` ```
In case of an error, the control jumps to the `catch` block. We can also wrap multiple lines: In the case of an error, the control jumps to the `catch` block. We can also wrap multiple lines:
```js run ```js run
async function f() { async function f() {
@ -263,15 +263,13 @@ f().catch(alert); // TypeError: failed to fetch // (*)
*/!* */!*
``` ```
If we forget to add `.catch` there, then we get an unhandled promise error (viewable in the console). We can catch such errors using a global event handler as described in the chapter <info:promise-error-handling>. If we forget to add `.catch` there, then we get an unhandled promise error (viewable in the console). We can catch such errors using a global `unhandledrejection` event handler as described in the chapter <info:promise-error-handling>.
```smart header="`async/await` and `promise.then/catch`" ```smart header="`async/await` and `promise.then/catch`"
When we use `async/await`, we rarely need `.then`, because `await` handles the waiting for us. And we can use a regular `try..catch` instead of `.catch`. That's usually (not always) more convenient. When we use `async/await`, we rarely need `.then`, because `await` handles the waiting for us. And we can use a regular `try..catch` instead of `.catch`. That's usually (but not always) more convenient.
But at the top level of the code, when we're outside of any `async` function, we're syntactically unable to use `await`, so it's a normal practice to add `.then/catch` to handle the final result or falling-through errors. But at the top level of the code, when we're outside any `async` function, we're syntactically unable to use `await`, so it's a normal practice to add `.then/catch` to handle the final result or falling-through error, like in the line `(*)` of the example above.
Like in the line `(*)` of the example above.
``` ```
````smart header="`async/await` works well with `Promise.all`" ````smart header="`async/await` works well with `Promise.all`"
@ -286,7 +284,7 @@ let results = await Promise.all([
]); ]);
``` ```
In case of an error, it propagates as usual: from the failed promise to `Promise.all`, and then becomes an exception that we can catch using `try..catch` around the call. In the case of an error, it propagates as usual, from the failed promise to `Promise.all`, and then becomes an exception that we can catch using `try..catch` around the call.
```` ````
@ -295,13 +293,13 @@ In case of an error, it propagates as usual: from the failed promise to `Promise
The `async` keyword before a function has two effects: The `async` keyword before a function has two effects:
1. Makes it always return a promise. 1. Makes it always return a promise.
2. Allows to use `await` in it. 2. Allows `await` to be used in it.
The `await` keyword before a promise makes JavaScript wait until that promise settles, and then: The `await` keyword before a promise makes JavaScript wait until that promise settles, and then:
1. If it's an error, the exception is generated, same as if `throw error` were called at that very place. 1. If it's an error, the exception is generated same as if `throw error` were called at that very place.
2. Otherwise, it returns the result. 2. Otherwise, it returns the result.
Together they provide a great framework to write asynchronous code that is easy both to read and write. Together they provide a great framework to write asynchronous code that is easy to both read and write.
With `async/await` we rarely need to write `promise.then/catch`, but we still shouldn't forget that they are based on promises, because sometimes (e.g. in the outermost scope) we have to use these methods. Also `Promise.all` is a nice thing to wait for many tasks simultaneously. With `async/await` we rarely need to write `promise.then/catch`, but we still shouldn't forget that they are based on promises, because sometimes (e.g. in the outermost scope) we have to use these methods. Also `Promise.all` is nice when we are waiting for many tasks simultaneously.