Promise.prototype.finally()
Базовый уровень Широко доступно
Эта функция хорошо зарекомендовала себя и работает на многих устройствах и версиях браузеров. Она доступна во всех браузерах с октября 2018 года.
Метод finally() экземпляров Promise планирует вызов функции, когда промис завершен (либо выполнен, либо отклонен). Он немедленно возвращает другой объект Promise, позволяя вам связывать вызовы других методов промисов в цепочку.
Как и блок finally, этот метод обычно предназначен для действий по очистке, независимо от результата промиса. Он позволяет избежать дублирования кода как в обработчиках then(), так и в обработчиках catch() промиса.
Попробуйте
function checkMail() {
return new Promise((resolve, reject) => {
if (Math.random() > 0.5) {
resolve("Mail has arrived");
} else {
reject(new Error("Failed to arrive"));
}
});
}
checkMail()
.then((mail) => {
console.log(mail);
})
.catch((err) => {
console.error(err);
})
.finally(() => {
console.log("Experiment completed");
});
Синтаксис
promiseInstance.finally(onFinally)
Параметры
-
onFinally - Функция для асинхронного выполнения, когда этот промис завершен. Если функция возвращает промис, результирующий промис будет ожидать завершения этого промиса, прежде чем продолжить. Если возвращенный промис отклонен, результирующий промис отклоняется по той же причине. Любое другое возвращаемое значение или выполненное значение возвращенного промиса игнорируется.
Возвращаемое значение
Немедленно возвращает новый Promise. Этот новый промис всегда находится в состоянии ожидания (pending) при возврате, независимо от статуса текущего промиса. Если onFinally вызывает ошибку или возвращает отклоненный промис, новый промис будет отклонен с этим значением. В противном случае новый промис завершится тем же состоянием, что и текущий промис.
Описание
Метод finally() может быть полезен, если вы хотите выполнить некоторую обработку или очистку после завершения промиса, независимо от его результата.
Метод finally() очень похож на вызов then(onFinally, onFinally). Однако есть пара отличий:
- При создании функции прямо в строке вы можете передать ее один раз, вместо того чтобы быть вынужденным объявлять ее дважды или создавать для нее переменную.
- Коллбэк
onFinallyне принимает никаких аргументов. Этот вариант использования предназначен именно для тех случаев, когда вас не интересует причина отклонения или значение выполнения, и, следовательно, нет необходимости их предоставлять. - Вызов
finally()обычно прозрачен и отражает конечное состояние исходного промиса. Например:- В отличие от
Promise.resolve(2).then(() => 77, () => 77), который возвращает промис, в конечном итоге выполненный со значением77,Promise.resolve(2).finally(() => 77)возвращает промис, в конечном итоге выполненный со значением2. - Аналогично, в отличие от
Promise.reject(3).then(() => 88, () => 88), который возвращает промис, в конечном итоге выполненный со значением88,Promise.reject(3).finally(() => 88)возвращает промис, в конечном итоге отклоненный с причиной3.
- В отличие от
Примечание: throw (или возврат отклоненного промиса) в колбэке finally все равно отклоняет возвращенный промис. Например, оба Promise.reject(3).finally(() => { throw 99; }) и Promise.reject(3).finally(() => Promise.reject(99)) отклоняют возвращенный промис с причиной 99.
Подобно catch(), finally() внутренне вызывает метод then на объекте, на котором он был вызван. Если onFinally не является функцией, then() вызывается с onFinally в качестве обоих аргументов, что для Promise.prototype.then() означает, что полезный обработчик не прикреплен. В противном случае then() вызывается с двумя внутренне созданными функциями, которые ведут себя следующим образом:
Предупреждение: Это предназначено только для демонстрационных целей и не является полифилом.
promise.then(
(value) => Promise.resolve(onFinally()).then(() => value),
(reason) =>
Promise.resolve(onFinally()).then(() => {
throw reason;
}),
);
Поскольку finally() вызывает then(), он поддерживает наследование (subclassing). Кроме того, обратите внимание на вызов Promise.resolve() выше — на самом деле, возвращаемое значение onFinally() разрешается с использованием того же алгоритма, что и Promise.resolve(), но фактическим конструктором, используемым для создания разрешенного промиса, будет подкласс. finally() получает этот конструктор через promise.constructor[Symbol.species].
Примеры
Использование finally()
let isLoading = true;
fetch(myRequest)
.then((response) => {
const contentType = response.headers.get("content-type");
if (contentType && contentType.includes("application/json")) {
return response.json();
}
throw new TypeError("Oops, we haven't got JSON!");
})
.then((json) => {
/* process your JSON further */
})
.catch((error) => {
console.error(error); // this line can also throw, e.g. when console = {}
})
.finally(() => {
isLoading = false;
});
Спецификации
Совместимость с браузерами
| Настольные | Мобильные | Серверные | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on iOS | Samsung Internet | WebView Android | WebView on iOS | Bun | Deno | Node.js | |
finally |
63 |
18 |
58 |
50 |
11.1 |
63 |
58 |
46 |
11.3 |
8.0 |
63 |
11.3 |
1.0.0 |
1.0 |
10.0.0 |
Смотрите также
- Полифил
Promise.prototype.finallyвcore-js - es-shims полифил
Promise.prototype.finally PromisePromise.prototype.then()Promise.prototype.catch()
© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally