📝实现一个 Promise(3)
关于 Promise 的其它问题
1. 如何停止一个 promise 链?
站在实现者的角度,当发生严重错误致使后面的链都没必要执行了的时候,可以返回一个永远 pending 的 promise。
return new Promise(() => { })但是,它会引入一个新的问题:链式调用后面的所有回调函数,都将无法被垃圾回收器回收。
Promise 应该在执行完所有回调后,删除对所有回调函数的引用以让它们能被回收。在之前自己实现 Promise 时,为了减少复杂度,并没有做这种处理。
思考:能否用一个函数变量或函数定义,来替代上面的匿名函数?答案是可以的,这样的话整个 promise 链就只有一份在内存里,不被回收也是可以接受的。
// 将其封装成一个更有语义的函数,提高可读性
Promise.cancel = Promise.stop = function () {
return new Promise(() => { })
}然后,就可以这样停止 promise 链了:
new Promise((resolve, reject) => {
resolve(35)
}).then((value) => {
// ...这里发生了严重错误
return Promise.stop() // 返回一个永远 pending 的 promise
}).catch()
.then()
.then()
.catch()
.then()2. 链上最后一个 promise 出错了怎么办?
在所有 promise 链的最后都加上 catch(),是可以确保之前发生的错误都能被捕获。然而,如果是最后一个 catch() 里出错了,如何捕捉?
2.1 新增 done()
done()方法一:提供一个 done 方法,将其列在链的最后。
就可以这样使用了:
本质上,这和开发人员在每个链后自己加 catch 没太大区别,只是函数由框架提供了而已。Q 就使用了 done 方法来达成类似的目的,$q 在最新的版本中也加入了类似的功能。
2.2 完善 reject 逻辑
reject 逻辑方法二:在实现 Promise 的 reject 的逻辑里,增加如下判断:
比如在执行如下代码时,由于 promise4 是真的没有任何回调,所以就会触发新增的 console.error()
Bluebird 和 ES6 Promise 都做了类似的处理,在 promise 被 reject 但又没有 callback 时,就把错误输出到控制台。
Last updated