You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 1-js/11-async/02-promise-basics/article.md
+22-22Lines changed: 22 additions & 22 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,15 +2,15 @@
2
2
3
3
Представьте, что вы известный певец, которого фанаты постоянно донимают расспросами о предстоящем сингле.
4
4
5
-
Чтобы получить передышку, вы обещаете разослать его им, когда он будет опубликован. Вы даете фанатам список, в который они могут записаться, чтобы получить новости. Они могут оставить свой e-mail, чтобы когда песня выйдет сразу получить её. И даже больше, если, например, вы передумаете выпускать песню, они также получат уведомление об этом.
5
+
Чтобы получить передышку, вы обещаете разослать им сингл, когда он будет выпущен. Вы даете фанатам список, в который они могут записаться, чтобы получать новости. Они могут оставить свой e-mail, чтобы когда песня выйдет сразу получить её. И даже больше, если, например, вы передумаете выпускать песню, они также получат уведомление об этом.
6
6
7
7
Все счастливы! Вы счастливы, потому что вас больше не донимают фанаты, а фанаты - могут больше не беспокоится, что пропустят новый сингл.
8
8
9
9
Это аналогия из реальной жизни для ситуаций, с которыми мы часто сталкиваемся в программировании:
10
10
11
11
1. "Певец" - это "создающий" код, который делает что-то, что занимает время. Например, скачивает новый скрипт.
12
12
2. "Фанаты" - это "потребляющий" код, который хочет получить результат "создающего" кода, когда он будет готов. Этот результат может быть необходим большому количеству функций.
13
-
3.*Promise* (обещание) - это специальный объект в JavaScript, который связывает "создающий" и "потребляющий" коды вместе. В терминах нашей аналогии - это "список подписок". "Создающий" код может выполнятся любое необходимое ему время, чтобы получить обещанный результат, а *обещание* делает результат доступным для всего кода, который подписан на него, когда результат готов.
13
+
3.*Promise* (обещание) - это специальный объект в JavaScript, который связывает "создающий" и "потребляющий" коды вместе. В терминах нашей аналогии - это "список подписок". "Создающий" код может выполнятся любое необходимое ему время, чтобы получить обещанный результат, а *промис* делает результат доступным для всего кода, который подписан на него, когда результат готов.
14
14
15
15
Аналогия не совсем точна, потому что объект Promise в JavaScript гораздо сложнее простого списка подписок: он обладает дополнительными возможностями и ограничениями. Но для начала и она хороша.
16
16
@@ -22,14 +22,14 @@ let promise = new Promise(function(resolve, reject) {
22
22
});
23
23
```
24
24
25
-
Функция, переданная в конструкцию `new Promise` называется *исполнитель*. Когда `Promise` создан, функция-исполнитель запускается автоматически. Она содержит "создающий" код, который когда-нибудь создать результат. В терминах аналогии: *исполнитель* - это "певец".
25
+
Функция, переданная в конструкцию `new Promise` называется *исполнитель*. Когда `Promise` создан, функция-исполнитель запускается автоматически. Она содержит "создающий" код, который когда-нибудь создаст результат. В терминах нашей аналогии: *исполнитель* - это "певец".
26
26
27
27
Объект `Promise`, полученный в результате выполнения конструктора, имеет внутренние свойства:
28
28
29
-
-`state` ("состояние") — вначале `pending` ("ожидание"), потом может измениться на `fulfilled` («выполнено успешно») or`rejected` ("выполнено с ошибкой"),
29
+
-`state` ("состояние") — вначале `pending` ("ожидание"), потом может измениться на `fulfilled` ("выполнено успешно") или`rejected` ("выполнено с ошибкой"),
30
30
-`result` ("результат") — имеет произвольное значение, по вашему выбору, изначально `undefined`.
31
31
32
-
Когда исполнитель завершает выполнение, он должен вызвать одну из функций, полученных в качестве аргументов:
32
+
Когда функция-исполнитель завершает своё выполнение, она должна вызвать одну из функций, полученных в качестве аргументов:
33
33
34
34
-`resolve(value)` — сообщает, что работа выполнена успешно:
35
35
- устанавливает в `state` значение `"fulfilled"`,
@@ -55,8 +55,8 @@ let promise = new Promise(function(resolve, reject) {
55
55
56
56
Мы можем наблюдать две вещи, запустив код выше:
57
57
58
-
1. Исполнитель вызывается автоматически и сразу (с помощью `new Promise`).
59
-
2. Исполнитель получает два аргумента: `resolve` и `reject` — эти функции встроены в JavaScript, поэтому нам не нужно их создавать. Вместо этого мы должны написать функцию-исполнитель, для их вызова по готовности.
58
+
1. Исполнитель будет вызван автоматически без задержек (с помощью `new Promise`).
59
+
2. Исполнитель получает два аргумента: `resolve` и `reject` — это функции встроенные в JavaScript, поэтому нам не нужно их писать. Вместо этого мы должны написать функцию-исполнитель, которая вызовет одну из них по готовности.
60
60
61
61
Спустя одну секунду "обработки" исполнитель вызовет `resolve("done")`, чтобы передать результат:
62
62
@@ -93,7 +93,7 @@ let promise = new Promise(function(resolve, reject) {
93
93
});
94
94
```
95
95
96
-
Идея в том, что задача выполненная исполнителем может иметь только что-то одно: результат или ошибку.
96
+
Идея в том, что задача выполняемая исполнителем может иметь только один итог: результат или ошибку.
97
97
98
98
Также, `resolve`/`reject` ожидает только один аргумент (или ни одного), а все дополнительные аргументы будут проигнорированы.
99
99
````
@@ -102,8 +102,8 @@ let promise = new Promise(function(resolve, reject) {
102
102
На случай, когда что-то пойдёт неправильно, `reject` может быть вызван аргументом любого типа (как и `resolve`). Но рекомендуется использовать объект `Error` (или унаследованный от него). "Почему так?" Скоро нам станет понятно.
Обычно, исполнитель делает что-то асинхронное и после этого вызывает `resolve`/`reject` через какое-то время, но это не обязательно. `resolve` или `reject` могут быть вызваны сразу, как в примере:
105
+
````smart header="Вызов `resolve`/`reject` сразу"
106
+
Обычно, исполнитель делает что-то асинхронное и после этого вызывает `resolve`/`reject` через какое-то время, но это не обязательно. `resolve` или `reject` могут быть вызваны сразу:
107
107
108
108
```js
109
109
let promise = new Promise(function(resolve, reject) {
@@ -118,7 +118,7 @@ let promise = new Promise(function(resolve, reject) {
118
118
````
119
119
120
120
```smart header="Свойства `state` и `result` - внутренние"
121
-
Свойства `state` и `result` - это внутренние свойства объекта `Promise` и мы не имеем к ним прямого доступа из "потребляющего" кода. Для этого следует использовать методы `.then`/`.catch`/`.finally`, про них речь пойдет дальше.
121
+
Свойства `state` и `result` - это внутренние свойства объекта `Promise` и мы не имеем к ним прямого доступа из "потребляющего" кода. Для обработки результата следует использовать методы `.then`/`.catch`/`.finally`, про них речь пойдет дальше.
122
122
```
123
123
124
124
## Потребители: then, catch, finally
@@ -138,17 +138,17 @@ promise.then(
138
138
);
139
139
```
140
140
141
-
Первый аргумент метода `.then` - функция, которая
141
+
Первый аргумент метода `.then` - функция, которая:
142
142
143
-
1. выполняется, когда `Promise` переходит в состояние `fulfilled`
143
+
1. выполняется, когда `Promise` переходит в состояние `fulfilled`, и
144
144
2. получает результат.
145
145
146
146
Второй аргумент `.then` - функция, которая:
147
147
148
-
1. выполняется, когда `Promise` переходит в состояние `rejected`
148
+
1. выполняется, когда `Promise` переходит в состояние `rejected`, и
149
149
2. получает ошибку.
150
150
151
-
Например, ниже реакции на успешно завершенный промис:
151
+
Например, ниже реакции на успешно выполненный промис:
152
152
153
153
```js run
154
154
let promise = new Promise(function(resolve, reject) {
@@ -209,11 +209,11 @@ promise.catch(alert); // выведет "Error: Whoops!" спустя одну
209
209
*/!*
210
210
```
211
211
212
-
Вызов `.catch(f)` - это сокращенный вариант `.then(null, f)`, внутри они полностью аналогичны.
212
+
Вызов `.catch(f)` - это сокращенный вариант `.then(null, f)`, внутри они полностью одинаковые.
213
213
214
214
### Метод finally (в конце)
215
215
216
-
По аналогии с блоком `finally` из обычного `try {...} catch {...}`, в `promise`, также есть метод `finally`
216
+
По аналогии с блоком `finally` из обычного `try {...} catch {...}`, в `promise`, также есть метод `finally`.
217
217
218
218
Вызов `.finally(f)` это тоже самое, что передать в `.then(f, f)`, в том смысле, что "потребляющий" код выполниться в любом случае, когда промис станет решённым: успешно или с ошибкой.
219
219
@@ -232,9 +232,9 @@ new Promise((resolve, reject) => {
232
232
.then(result => show result, err => show error)
233
233
```
234
234
235
-
Это не совсем псевдоним, как можно подумать. Существует несколько важных отличий:
235
+
Это не совсем псевдоним, как можно было подумать. Существует несколько важных отличий:
236
236
237
-
1. Обработчик, вызываемый из `finally` не имеет аргументов. Мы не знаем, как в `finally` был завершён `Promise`. И это нормально, потому что обычно, наша задача - выполнить "главные" завершающие процедуры.
237
+
1. Обработчик, вызываемый из `finally` не имеет аргументов. В `finally` мы не знаем, как был завершён `Promise`. И это нормально, потому что обычно, наша задача - выполнить "основные" завершающие процедуры.
238
238
2. `Finally` пропустит результат или ошибку к следующим обработчикам.
239
239
240
240
Например, здесь результат проходит через `finally` к `then`:
@@ -263,15 +263,15 @@ new Promise((resolve, reject) => {
263
263
3. Последнее, но не менее значимое, у метода `.finally(f)` более удобный синтаксис, чем у`.then(f, f)`: не надо дублировать функции.
Если `promise` в состоянии ожидания, обработчики в `.then/catch/finally` будут ждать окончания. Однако, если `promise` уже решён, тогда они выполнятся сразу:
266
+
Если промис в состоянии ожидания, обработчики в `.then/catch/finally` будут ждать его окончания. Однако, если `promise` уже решён, тогда обработчики выполнятся сразу:
267
267
268
268
```js run
269
269
// мгновенный перевод `promise` в состояние решён
270
270
let promise = new Promise(resolve => resolve("done!"));
271
271
272
272
promise.then(alert); // done! (выведется сразу)
273
273
```
274
-
Хорошо то, что обработчик `.then` гарантированно запустится независимо от того, установится `Promise` мгновенно, или через какое-то время.
274
+
Хорошо то, что обработчик `.then` гарантированно будет запущен независимо от того, был ли `Promise` выполнен мгновенно, или находится в состоянии ожидания.
275
275
````
276
276
277
277
Теперь, рассмотрим несколько практических примеров того, как `Promise` может облегчить нам написание асинхронного кода.
@@ -296,7 +296,7 @@ function loadScript(src, callback) {
296
296
297
297
Теперь перепишем её используя `Promise`.
298
298
299
-
Новой функции `loadScript` не требуется аргумент callback. Вместо этого она будет создавать и возвращать объект `Promise`, который будет переходить в состояние решён, когда загрузка закончится. Внешний код может добавлять обработчики (функции-подписчиков) используя для этого метод `.then`:
299
+
Новой функции `loadScript`будет не нужен аргумент callback. Вместо этого она будет создавать и возвращать объект `Promise`, который будет переходить в состояние решён, когда загрузка закончится. Внешний код может добавлять обработчики (функции-подписчиков) используя для этого метод `.then`:
0 commit comments