Promise.prototype.finally()
finally()
方法是 Promise
实例的一个方法,用于安排一个函数,在 promise 完成(fulfilled)或拒绝(rejected)时调用。它会立即返回另一个 Promise
对象,允许您链式调用其他 promise 方法。
试一试
语法
promiseInstance.finally(onFinally)
参数
onFinally
-
一个函数,当此 promise 完成时异步执行。除非返回值是一个被拒绝的 promise,否则它的返回值会被忽略。该函数在没有参数的情况下被调用。
返回值
立即返回一个新的 Promise
。无论当前 promise 的状态如何,此新 promise 在返回时始终处于挂起状态。如果 onFinally
抛出错误或返回一个被拒绝的 promise,则新 promise 将会拒绝并使用该值。否则,新 promise 将会与当前 promise 具有相同的状态。
描述
如果您希望在 promise 完成后进行一些处理或清理,无论其结果如何,finally()
方法都很有用。
finally()
方法与调用 then(onFinally, onFinally)
非常相似。但是,它们之间存在一些差异
- 在内联创建函数时,您可以传递一次,而不是被迫声明两次或为其创建一个变量。
onFinally
回调不接收任何参数。此用例用于您不在乎拒绝原因或完成值的情况,因此无需提供它。finally()
调用通常是透明的,并反映原始 promise 的最终状态。例如- 与
Promise.resolve(2).then(() => 77, () => {})
不同,后者返回一个最终以值77
完成的 promise,Promise.resolve(2).finally(() => 77)
返回一个最终以值2
完成的 promise。 - 类似地,与
Promise.reject(3).then(() => {}, () => 88)
不同,后者返回一个最终以值88
完成的 promise,Promise.reject(3).finally(() => 88)
返回一个最终以原因3
拒绝的 promise。
- 与
注意:finally
回调中的 throw
(或返回被拒绝的 promise)仍然会拒绝返回的 promise。例如,Promise.reject(3).finally(() => { throw 99; })
和 Promise.reject(3).finally(() => Promise.reject(99))
都以原因 99
拒绝返回的 promise。
与 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()
相同的算法进行解析,但用于构造解析 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 语言规范 # sec-promise.prototype.finally |
浏览器兼容性
BCD 表格仅在启用 JavaScript 的浏览器中加载。