Open AIluffy opened 6 years ago
promise.finally 的回调为毛要用 Promise.resolve(fun()).then(() => value) 这样的方式进行处理,直接 fun(); return value 不是一样的吗?
88行
if (typeod Promise.prototype.done !== 'function') {
Promise.prototype.finally = function(onFinally) {
...
应该是
if (typeod Promise.prototype.finally !== 'function') {
Promise.prototype.finally = function(onFinally) {
...
Promise已经像血液一样融入到我们的日常工作中,thenable无时无刻不在发挥着它的作用。网络上关于Promise的文章也是汗牛充栋,人们一遍又一遍的咀嚼着Promise.prototype.then, Promise.prototype.catch的作用和功效。
很多时候,我们的执行函数会是p.then(onFulfilled).catch(onRejected)这种形式,并不会链接太多操作,这有点像try语句。
有时候,我们希望一个操作,无论是否抛出异常都会执行,即不管它进入了resolve,还是reject,下一步操作都会执行。比如我们发送请求之前会出现一个loading图,当我们请求发送完成之后,不管请求有没有出错,我们都希望关掉这个loading图以提升用户体验。过去我们可以这么做:
这种写法一点也不DRY,显得丑陋。为了让代码稍微好看一点,我们也可以这么写:
这么写虽然让我们舒服了点,但是,总感觉哪里怪怪的,总觉得.then后面还有.catch。作为类比,我们可以看一下try语句的三种声明形式:
那么问题来了,为什么Promise没有实现finally的写法,用于在任何情况下(不论成功或者失败)执行特定后续操作。这样在语义上,代码显得更加直观与合理。
好消息是,Promise.prototype.finally已于2018/01/24进入ES8的stage4阶段。半数以上的浏览器也做出了兼容。我们现在就可以尝鲜使用了。
于是上面的例子就变成了这样:
看起来好像也没有什么区别,但其实使用Promise.finally(onFinally) 和 Promise.then(onFulfilled, onRejected)还是有以下几点不同:
1、2两点容易理解,至于3、4,可以通过下面的两个例子进行说明:
如果浏览器没有实现finally,那么可以实现polyfill:
通过该polyfill,可以更加理解为什么finally()会透传fullfilled的值和rejected错误。
Promise.prototype.finally()会返回一个promise对象,Promise chain会延续下去。但是如果我们不想这条Promise chain继续执行下去,而想在执行一个操作后关闭Promise chain。这种时候就需要用到Promise.prototype.done().
Promise.prototype.done的使用方法和then一样,但是该方法不会返回Promise对象。
实现Promise.prototype.done的polyfill如下:
可以看到,Promise.prototype.done和Promise.prototype.finally存在两点不同:
以上便是Promise.prototype.finally和Promise.prototype.done的介绍和说明,也许实际使用的频率不会很高,但是为了高可读的代码,大家不妨一试。 (ゝ∀・)
参考