无法取消 Promise

前端精髓

共 1253字,需浏览 3分钟

 ·

2021-12-11 15:42


Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。


所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。


(1)对象的状态不受外界影响。Promise 对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是 Promise 这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。


(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从 pending 变为 fulfilled 和从 pending 变为 rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对 Promise 对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。


Promise 也有一些缺点。首先,无法取消 Promise,一旦新建它就会立即执行,无法中途取消。


Promise 不能被取消,真的算是它的缺点吗?


其实还好,多数情况下,我们要取消的不是 Promise,而是生成 Promise 的那个任务。


而且这个任务本身的取消,有时还附带清理现场的需求,比方说,我 await 了一个存储文件的任务,那么取消这个存储文件任务,意味着中断文件写入,把已经写入的一些信息回滚等等操作。单纯从 Promise 的角度取消,其实只是取消了 Promise 后的回调,原本的任务还是执行完成了,若真设计出取消功能,很容易造成误判。


此外,当真正需要取消时,我们完全可以在 await 之后或者 then 的回调中加入控制逻辑,这能够保证代码逻辑紧凑,否则,我们调试时可能面临“ Promise 被取消时到处找取消的代码”这样的窘境。


综上,我认为 Promise 的取消功能不能说完全没用,至少在我看来没什么必要性,甚至不是什么好的实践。不能被取消,更谈不上设计缺点了。


我们多数情况下需要取消语义是为了通过减少无用计算来节约计算资源,所以通常来说这并不是一个太大的问题,它只会白白消耗计算资源,并不会造成错误。而且如果你需要的话,你也可以比较容易地在提供这个 Promise 的地方实现。


浏览 37
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报