Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions 1-js/11-async/02-promise-basics/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ let promise = new Promise(function(resolve, reject) {

```js
let promise = new Promise(function(resolve, reject) {
// эта функция выполнится автоматически, при вызове new Promise
// эта функция выполнится автоматически при вызове new Promise

// через 1 секунду сигнализировать, что задача выполнена с результатом "done"
setTimeout(() => *!*resolve("done")*/!*, 1000);
Expand Down Expand Up @@ -213,21 +213,21 @@ promise.catch(alert); // выведет "Error: Ошибка!" спустя од

## Очистка: finally

По аналогии с блоком `finally` из обычного `try {...} catch {...}`, у промисов также есть метод `finally`.
По аналогии с блоком `finally` из обычного `try {...} catch {...}` у промисов также есть метод `finally`.

Вызов `.finally(f)` похож на `.then(f, f)`, в том смысле, что `f` выполнится в любом случае, когда промис завершится: успешно или с ошибкой.

Идея `finally` состоит в том, чтобы настроить обработчик для выполнения очистки/доведения после завершения предыдущих операций.

Например, остановка индикаторов загрузки, закрытие больше не нужных соединений и т.д.

Думайте об этом как о завершении вечеринки. Независимо от того, была ли вечеринка хорошей или плохой, сколько на ней было друзей, нам все равно нужно (или, по крайней мере, мы должны) сделать уборку после нее.
Думайте об этом как о завершении вечеринки. Независимо от того, была ли вечеринка хорошей или плохой, сколько на ней было друзей, нам всё равно нужно (или, по крайней мере, мы должны) сделать уборку после неё.

Код может выглядеть следующим образом:

```js
new Promise((resolve, reject) => {
/* сделать что-то, что займёт время, и после вызвать resolve или может reject */
/* сделать что-то, что займёт время, и после вызвать resolve или, может, reject */
})
*!*
// выполнится, когда промис завершится, независимо от того, успешно или нет
Expand Down Expand Up @@ -257,7 +257,7 @@ new Promise((resolve, reject) => {
.then(result => alert(result)); // <-- .then показывает "value"
```

Как вы можете видеть, значение возвращаемое первым промисом, передается через `finally` к следующему `then`.
Как вы можете видеть, значение, возвращаемое первым промисом, передаётся через `finally` к следующему `then`.

Это очень удобно, потому что `finally` не предназначен для обработки результата промиса. Как уже было сказано, это место для проведения общей очистки, независимо от того, каков был результат.

Expand All @@ -273,15 +273,15 @@ new Promise((resolve, reject) => {

3. Обработчик `finally` также не должен ничего возвращать. Если это так, то возвращаемое значение молча игнорируется.

Единственным исключением из этого правила является случай, когда обработчик `finally` выдает ошибку. Затем эта ошибка передается следующему обработчику вместо любого предыдущего результата.
Единственным исключением из этого правила является случай, когда обработчик `finally` выдаёт ошибку. Затем эта ошибка передаётся следующему обработчику вместо любого предыдущего результата.

Подведем итог:
Подведём итог:

- Обработчик `finally` не получает результат предыдущего обработчика (у него нет аргументов). Вместо этого этот результат передается следующему подходящему обработчику.
- Обработчик `finally` не получает результат предыдущего обработчика (у него нет аргументов). Вместо этого результат передаётся следующему подходящему обработчику.
- Если обработчик `finally` возвращает что-то, это игнорируется.
- Когда `finally` выдает ошибку, выполнение переходит к ближайшему обработчику ошибок.
- Когда `finally` выдаёт ошибку, выполнение переходит к ближайшему обработчику ошибок.

Эти функции полезны и заставляют все работать правильно, если мы используем `finally` так, как предполагается: для общих процедур очистки.
Эти функции полезны и заставляют всё работать правильно, если мы используем `finally` так, как предполагается: для общих процедур очистки.

````smart header="На завершённых промисах обработчики запускаются сразу"
Если промис в состоянии ожидания, обработчики в `.then/catch/finally` будут ждать его.
Expand Down Expand Up @@ -320,7 +320,7 @@ function loadScript(src, callback) {

Теперь перепишем её, используя `Promise`.

Новой функции `loadScript` более не нужен аргумент `callback`. Вместо этого она будет создавать и возвращать объект `Promise`, который перейдет в состояние "успешно завершён", когда загрузка закончится. Внешний код может добавлять обработчики ("подписчиков"), используя `.then`:
Новой функции `loadScript` более не нужен аргумент `callback`. Вместо этого она будет создавать и возвращать объект `Promise`, который перейдёт в состояние "успешно завершён", когда загрузка закончится. Внешний код может добавлять обработчики ("подписчиков"), используя `.then`:

```js run
function loadScript(src) {
Expand Down Expand Up @@ -354,7 +354,7 @@ promise.then(script => alert('Ещё один обработчик...'));

| Промисы | Колбэки |
|----------|-----------|
| Промисы позволяют делать вещи в естественном порядке. Сперва мы запускаем `loadScript(script)`, и затем (`.then`) мы пишем, что делать с результатом. | У нас должна быть функция`callback` на момент вызова `loadScript(script, callback)`. Другими словами, нам нужно знать что делать с результатом *до того*, как вызовется `loadScript`. |
| Промисы позволяют делать вещи в естественном порядке. Сперва мы запускаем `loadScript(src)`, и затем (`.then`) мы пишем, что делать с результатом. | У нас должна быть функция`callback` на момент вызова `loadScript(src, callback)`. Другими словами, нам нужно знать, что делать с результатом *до того*, как вызовется `loadScript`. |
| Мы можем вызывать `.then` у `Promise` столько раз, сколько захотим. Каждый раз мы добавляем нового "фаната", новую функцию-подписчика в "список подписок". Больше об этом в следующей главе: [](info:promise-chaining). | Колбэк может быть только один. |

Таким образом, промисы позволяют улучшить порядок кода и дают нам гибкость. Но это далеко не всё. Мы узнаем ещё много полезного в последующих главах.