Skip to content

Commit 50df0c8

Browse files
committed
Merge branch 'master' of github.com:javascript-tutorial/en.javascript.info into sync-14e4e9f9
2 parents 028d718 + 14e4e9f commit 50df0c8

File tree

2 files changed

+23
-29
lines changed

2 files changed

+23
-29
lines changed

1-js/11-async/03-promise-chaining/article.md

+5-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
# Promises chaining
33

4-
Let's return to the problem mentioned in the chapter <info:callbacks>: we have a sequence of asynchronous tasks to be done one after another. For instance, loading scripts. How can we code it well?
4+
Let's return to the problem mentioned in the chapter <info:callbacks>: we have a sequence of asynchronous tasks to be performed one after another — for instance, loading scripts. How can we code it well?
55

66
Promises provide a couple of recipes to do that.
77

@@ -164,7 +164,7 @@ loadScript("/article/promise-chaining/one.js")
164164

165165
Here each `loadScript` call returns a promise, and the next `.then` runs when it resolves. Then it initiates the loading of the next script. So scripts are loaded one after another.
166166

167-
We can add more asynchronous actions to the chain. Please note that the code is still "flat", it grows down, not to the right. There are no signs of "pyramid of doom".
167+
We can add more asynchronous actions to the chain. Please note that the code is still "flat"it grows down, not to the right. There are no signs of the "pyramid of doom".
168168

169169
Technically, we could add `.then` directly to each `loadScript`, like this:
170170

@@ -287,7 +287,7 @@ fetch('/article/promise-chaining/user.json')
287287
});
288288
```
289289

290-
The code works, see comments about the details. However, there's a potential problem in it, a typical error of those who begin to use promises.
290+
The code works; see comments about the details. However, there's a potential problem in it, a typical error for those who begin to use promises.
291291

292292
Look at the line `(*)`: how can we do something *after* the avatar has finished showing and gets removed? For instance, we'd like to show a form for editing that user or something else. As of now, there's no way.
293293

@@ -319,13 +319,9 @@ fetch('/article/promise-chaining/user.json')
319319
.then(githubUser => alert(`Finished showing ${githubUser.name}`));
320320
```
321321

322-
That is, `.then` handler in line `(*)` now returns `new Promise`, that becomes settled only after the call of `resolve(githubUser)` in `setTimeout` `(**)`.
322+
That is, the `.then` handler in line `(*)` now returns `new Promise`, that becomes settled only after the call of `resolve(githubUser)` in `setTimeout` `(**)`. The next `.then` in the chain will wait for that.
323323

324-
The next `.then` in chain will wait for that.
325-
326-
As a good practice, an asynchronous action should always return a promise.
327-
328-
That makes it possible to plan actions after it. Even if we don't plan to extend the chain now, we may need it later.
324+
As a good practice, an asynchronous action should always return a promise. That makes it possible to plan actions after it; even if we don't plan to extend the chain now, we may need it later.
329325

330326
Finally, we can split the code into reusable functions:
331327

1-js/11-async/08-async-await/article.md

+18-20
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ async function f() {
1414

1515
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.
1616

17-
For instance, this function returns a resolved promise with the result of `1`, let's test it:
17+
For instance, this function returns a resolved promise with the result of `1`; let's test it:
1818

1919
```js run
2020
async function f() {
@@ -24,7 +24,7 @@ async function f() {
2424
f().then(alert); // 1
2525
```
2626

27-
...We could explicitly return a promise, that would be the same:
27+
...We could explicitly return a promise, which would be the same:
2828

2929
```js run
3030
async function f() {
@@ -67,7 +67,7 @@ f();
6767

6868
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.
6969

70-
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.
70+
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.
7171

7272
It's just a more elegant syntax of getting the promise result than `promise.then`, easier to read and write.
7373

@@ -130,7 +130,7 @@ let response = await fetch('/article/promise-chaining/user.json');
130130
let user = await response.json();
131131
```
132132
133-
We can wrap it into an anonymous async function, like this:
133+
But we can wrap it into an anonymous async function, like this:
134134
135135
```js
136136
(async () => {
@@ -143,9 +143,9 @@ We can wrap it into an anonymous async function, like this:
143143
144144
````
145145
````smart header="`await` accepts \"thenables\""
146-
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`.
146+
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`.
147147

148-
Here's a demo `Thenable` class, the `await` below accepts its instances:
148+
Here's a demo `Thenable` class; the `await` below accepts its instances:
149149

150150
```js run
151151
class Thenable {
@@ -168,7 +168,7 @@ async function f() {
168168
f();
169169
```
170170

171-
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.
171+
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.
172172
````
173173
174174
````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
192192
````
193193
## Error handling
194194

195-
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.
195+
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.
196196

197197
This code:
198198

@@ -204,7 +204,7 @@ async function f() {
204204
}
205205
```
206206

207-
...Is the same as this:
207+
...is the same as this:
208208

209209
```js
210210
async function f() {
@@ -233,7 +233,7 @@ async function f() {
233233
f();
234234
```
235235

236-
In case of an error, the control jumps to the `catch` block. We can also wrap multiple lines:
236+
In the case of an error, the control jumps to the `catch` block. We can also wrap multiple lines:
237237

238238
```js run
239239
async function f() {
@@ -263,15 +263,13 @@ f().catch(alert); // TypeError: failed to fetch // (*)
263263
*/!*
264264
```
265265

266-
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>.
266+
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>.
267267

268268

269269
```smart header="`async/await` and `promise.then/catch`"
270-
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.
270+
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.
271271

272-
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.
273-
274-
Like in the line `(*)` of the example above.
272+
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.
275273
```
276274
277275
````smart header="`async/await` works well with `Promise.all`"
@@ -286,7 +284,7 @@ let results = await Promise.all([
286284
]);
287285
```
288286

289-
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.
287+
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.
290288

291289
````
292290
@@ -295,13 +293,13 @@ In case of an error, it propagates as usual: from the failed promise to `Promise
295293
The `async` keyword before a function has two effects:
296294
297295
1. Makes it always return a promise.
298-
2. Allows to use `await` in it.
296+
2. Allows `await` to be used in it.
299297
300298
The `await` keyword before a promise makes JavaScript wait until that promise settles, and then:
301299
302-
1. If it's an error, the exception is generated, same as if `throw error` were called at that very place.
300+
1. If it's an error, the exception is generated same as if `throw error` were called at that very place.
303301
2. Otherwise, it returns the result.
304302
305-
Together they provide a great framework to write asynchronous code that is easy both to read and write.
303+
Together they provide a great framework to write asynchronous code that is easy to both read and write.
306304
307-
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.
305+
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.

0 commit comments

Comments
 (0)