在 ECMAScript 2018( ES2018 ) 新功能 我们介绍了 TC39 会议已经票选出了 ES2018 的新功能
本着每一小节一个新功能的原则,本小节我们介绍另一个新功能,Promise.prototype.finally()
Promise.prototype.finally()
Promise.prototype.finally() 用于最终完成整个 promises
实现,允许我们注册一个回调函数用于在一个 promise
被解决 ( 被满足或被拒绝 ) 时被调用
一个典型的用例是在 fetch()
请求之后隐藏一个微调器,与其在最后一个 .then()
和 .catch()
之间复制相同的逻辑,还不如直接将这些逻辑放在 .finally()
中
fetch('http://example.com/endpoint') .then(result => { // ... }) .catch((err) => { // ... }) .finally(() => { // cleanup here })
愿景
许多 promise
库都有一个 finally()
方法,用于注册一个在 promise
被解决 ( 被满足或被拒绝 ) 时被调用的回调函数
finally()
方法一般用于清理环境,释放变量等等,比如想在 AJAX 请求中隐藏 「 加载 」微调器,或者关闭打开的任何文件句柄,或者记录操作已完成,无论这个 AJAX 操作成功与否
为什么不是 .then(f, f)
?
很多人可能会说要不再添加一个 .then(f,f)
函数,因为 promise.finally(func)
看起来非常像 promise.then(func,func)
其实,它们有几个关键方面的区别
-
使用
promise.finally(func)
创建的内联函数func
,只需要传递一次,而不是像.then(f,f)
强制要求它两次,或者为它创建一个变量 -
promise.finally(func)
回调不需要,也不会收到任何参数。因为没有可靠的方法来确定promise
是否已履行或被拒绝。 因为使用finally()
时,我们根本就不需要关心拒绝原因或履行价值的情况,因此无需提供 -
与
Promise.resolve(2).then(() => {}, () => {})
履行的结果为undefined
不同,Promise.resolve(2).finally(() => {})
履行的结果为2
-
同样的,与
Promise.reject(3).then(() => {}, () => {})
拒绝的结果为undefined
不同,Promise.reject(3).finally(() => {})
拒绝的结果为3
请注意:在
finally()
回调中throw
( 或返回被拒绝的承诺 ) 将拒绝具有该拒绝原因的新promise