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
+24-9Lines changed: 24 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,3 +1,4 @@
1
+
1
2
# Промисы
2
3
3
4
Представьте, что вы известный певец, которого фанаты постоянно донимают расспросами о предстоящем сингле.
@@ -210,7 +211,7 @@ promise.catch(alert); // выведет "Error: Ошибка!" спустя од
210
211
211
212
Вызов `.catch(f)` - это сокращённый, "укороченный" вариант `.then(null, f)`.
212
213
213
-
### finally
214
+
## Очистка: finally
214
215
215
216
По аналогии с блоком `finally` из обычного `try {...} catch {...}`, у промисов также есть метод `finally`.
216
217
@@ -234,32 +235,46 @@ new Promise((resolve, reject) => {
234
235
Но это не совсем псевдоним `then(f,f)`, как можно было подумать. Существует несколько важных отличий:
235
236
236
237
1. Обработчик, вызываемый из `finally`, не имеет аргументов. В `finally` мы не знаем, как был завершён промис. И это нормально, потому что обычно наша задача - выполнить "общие" завершающие процедуры.
238
+
239
+
Пожалуйста, взгляните на приведенный выше пример: как вы можете видеть, обработчик `finally` не имеет аргументов, а результат promise обрабатывается в следующем обработчике.
240
+
237
241
2. Обработчик `finally` "пропускает" результат или ошибку дальше, к последующим обработчикам.
238
242
239
243
Например, здесь результат проходит через `finally` к `then`:
244
+
240
245
```js run
241
246
new Promise((resolve, reject) => {
242
247
setTimeout(() => resolve("result"), 2000)
243
248
})
244
-
.finally(() => alert("Промис завершён"))
245
-
.then(result => alert(result)); // <-- .then обработает результат
249
+
.finally(() => alert("Промис завершён")) // срабатывает первым
250
+
.then(result => alert(result)); // <-- .then показывает "значение"
246
251
```
247
-
252
+
253
+
Как вы можете видеть, значение возвращаемое первым промисом, передается через `finally` к следующему `then`.
254
+
255
+
Это очень удобно, потому что `finally` не предназначен для обработки результата промиса. Как уже было сказано, это место для проведения общей очистки, независимо от того, каков был результат.
256
+
248
257
А здесь ошибка из промиса проходит через `finally` к `catch`:
249
258
250
259
```js run
251
260
new Promise((resolve, reject) => {
252
261
throw new Error("error");
253
262
})
254
-
.finally(() => alert("Промис завершён"))
255
-
.catch(err => alert(err)); // <-- .catch обработает объект ошибки
263
+
.finally(() => alert("Промис завершён")) // срабатывает первым
264
+
.catch(err => alert(err)); // <-- .catch показывает ошибку
256
265
```
257
266
258
-
Это очень удобно, потому что `finally` не предназначен для обработки результата промиса. Так что он просто пропускает его через себя дальше.
267
+
3. Обработчик `finally` также не должен ничего возвращать. Если это так, то возвращаемое значение молча игнорируется.
268
+
269
+
Единственным исключением из этого правила является случай, когда обработчик `finally` выдает ошибку. Затем эта ошибка передается следующему обработчику вместо любого предыдущего результата.
270
+
271
+
Подведем итог:
259
272
260
-
Мы более подробно поговорим о создании цепочек промисов и передаче результатов между обработчиками в следующей главе.
273
+
- Обработчик `finally` не получает результат предыдущего обработчика (у него нет аргументов). Вместо этого этот результат передается следующему подходящему обработчику.
274
+
- Если обработчик `finally` возвращает что-то, это игнорируется.
275
+
- Когда `finally` выдает ошибку, выполнение переходит к ближайшему обработчику ошибок.
261
276
262
-
3. Последнее, но не менее значимое: вызов `.finally(f)` удобнее, чем `.then(f, f)` - не надо дублировать функции f.
277
+
Эти функции полезны и заставляют все работать правильно, если мы используем `finally` так, как предполагается: для общих процедур очистки.
Если промис в состоянии ожидания, обработчики в `.then/catch/finally` будут ждать его. Однако, если промис уже завершён, то обработчики выполнятся сразу:
0 commit comments