大家好,我卡颂。
遥想数年前的一次面试,面试官问我:promise有什么缺点?
真是百思不得姐啊...
答案是:promise一旦初始化,就不能中止。这是由promise的实现决定的。
AbortSignal的出现使promise从语义上变为可中止的。并且,只要符合规范,所有异步操作都能变为「可中止的」。
AbortSignal是个实验性API,不过兼容性还不错,而且polyfill实现起来也不复杂。
AbortSignal可以实例化一个「信号对象」(signal object)。
AbortController可以实例化一个「信号对象」的控制器。
就像遥控器可以发出信号关电视一样,AbortController的实例可以控制中止信号。
只要符合AbortSignal的接入规范,任何异步操作都能实现中止功能。
举个例子,首先new一个控制器实例:
- // 控制器实例
- const controller = new AbortController();
- const signal = controller.signal;
其中signal是控制器对应的「信号对象」。
「信号对象」可以监听abort事件,当信号被中止时被触发。
调用controller.abort()方法后会中止信号,此时signal.aborted为true。
- // 监听 abort 事件
- signal.addEventListener('abort', () => {
- console.log("信号中止!")
- });
- // 控制器中止信号
- controller.abort();
- console.log('是否中止:', signal.aborted);
如上代码调用后会依次打印:
fetch API已经集成了AbortSignal。
只需要将controller内的「信号对象」作为signal参数传给fetch:
- const controller = new AbortController();
- fetch(url, {
- signal: controller.signal
- });
当调用controller.abort()后,fetch的promise会变为AbortError DOMException reject:
- fetch('xxxx', {
- signal: controller.signal
- }).then(() => {}, err => {
- if (err.name == 'AbortError') {
- // 中止信号
- } else {
- // 其他错误
- }
- })
可以在此时处理中止后的操作。
这里有个取消视频下载Demo[1],可以看看fetch如何配合AbortSignal实现取消下载
不仅是fetch,任何异步操作只要符合如下规范,都可以与AbortError集成:
如果API应用场景比较复杂(比如需要考虑多线程通信),文档中提供了一套基于「订阅发布」的abort-algorithms[2]机制来完成步骤4。
虽然AbortSignal原理很简单,但只要遵守接入规范,他的可扩展性是很强的。
比如,可以将一个signal传给多个符合规范的API,就能用一个控制器中止多个API的调用。
就像一个遥控器,同时操作家里的空调、电视、洗衣机,你爱了么?
[1]取消视频下载Demo:
https://mdn.github.io/dom-examples/abort-api/[2]abort-algorithms:
https://dom.spec.whatwg.org/#abortsignal-abort-algorithms
当前题目:AbortSignal:以前我没得选,现在我想中止Promise
文章出自:http://www.shufengxianlan.com/qtweb/news5/375655.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联