Promise.prototype.finally()
finally() 方法用于 Promise 实例,安排一个函数在 Promise 状态确定(fulfilled 或 rejected)时被调用。它会立即返回另一个 Promise 对象,使你可以 链式调用 其他 Promise 方法。
试一试
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 状态确定时异步执行的函数。除非返回值是一个被拒绝的 Promise,否则其返回值将被忽略。该函数不带任何参数调用。
返回值
立即返回一个新的 Promise。这个新 Promise 在返回时始终处于 pending 状态,无论当前 Promise 的状态如何。如果 onFinally 抛出错误或返回一个被拒绝的 Promise,新 Promise 将以该值被拒绝。否则,新 Promise 将以与当前 Promise 相同的状态确定。
描述
如果你想在 Promise 状态确定后执行一些处理或清理工作,而不考虑其结果,那么 finally() 方法会很有用。
finally() 方法非常类似于调用 then(onFinally, onFinally)。然而,有几点不同:
- 当内联创建函数时,你可以只传递一次,而不是被迫声明两次,或者为它创建一个变量。
onFinally回调不接收任何参数。这种情况适用于你不关心拒绝原因或 fulfilled 值的情况,因此没有必要提供它。finally()调用通常是透明的,并且反映了原始 Promise 的最终状态。例如:- 与
Promise.resolve(2).then(() => 77, () => {})(它返回一个最终 fulfilled 为77的 Promise)不同,Promise.resolve(2).finally(() => 77)返回一个最终 fulfilled 为2的 Promise。 - 同样,与
Promise.reject(3).then(() => {}, () => 88)(它返回一个最终 fulfilled 为88的 Promise)不同,Promise.reject(3).finally(() => 88)返回一个最终 rejected 为3的 Promise。
- 与
注意: 在 finally 回调中 throw(或返回一个被拒绝的 Promise)仍然会拒绝返回的 Promise。例如,Promise.reject(3).finally(() => { throw 99; }) 和 Promise.reject(3).finally(() => Promise.reject(99)) 都将返回的 Promise 以原因 99 拒绝。
与 catch() 类似,finally() 在内部调用其调用对象上的 then 方法。如果 onFinally 不是一个函数,then() 将使用 onFinally 作为两个参数调用——对于 Promise.prototype.then() 来说,这意味着没有附加有用的处理器。否则,then() 将使用两个内部创建的函数调用,这些函数表现如下:
警告: 这仅用于演示目的,并非 polyfill。
promise.then(
(value) => Promise.resolve(onFinally()).then(() => value),
(reason) =>
Promise.resolve(onFinally()).then(() => {
throw reason;
}),
);
因为 finally() 调用 then(),所以它支持子类化。此外,请注意上面的 Promise.resolve() 调用——实际上,onFinally() 的返回值使用与 Promise.resolve() 相同的算法进行 resolve,但用于构造已 resolve Promise 的实际构造函数将是子类。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;
});
规范
| 规范 |
|---|
| ECMAScript® 2026 语言规范 # sec-promise.prototype.finally |
浏览器兼容性
加载中…