前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >AbortSignal:以前我没得选,现在我想中止promise

AbortSignal:以前我没得选,现在我想中止promise

作者头像
公众号@魔术师卡颂
发布2021-10-12 14:49:39
7940
发布2021-10-12 14:49:39
举报
文章被收录于专栏:魔术师卡颂魔术师卡颂

大家好,我卡颂。

遥想数年前的一次面试,面试官问我:promise有什么缺点?

真是百思不得姐啊...

答案是:promise一旦初始化,就不能中止。这是由promise的实现决定的。

AbortSignal的出现使promise从语义上变为可中止的。并且,只要符合规范,所有异步操作都能变为「可中止的」

AbortSignal是什么

AbortSignal是个实验性API,不过兼容性还不错,而且polyfill实现起来也不复杂。

AbortSignal可以实例化一个「信号对象」signal object)。

AbortController可以实例化一个「信号对象」的控制器。

就像遥控器可以发出信号关电视一样,AbortController的实例可以控制中止信号。

只要符合AbortSignal的接入规范,任何异步操作都能实现中止功能。

举个例子,首先new一个控制器实例:

代码语言:javascript
复制
// 控制器实例
const controller = new AbortController();
const signal = controller.signal;

其中signal是控制器对应的「信号对象」

「信号对象」可以监听abort事件,当信号被中止时被触发。

调用controller.abort()方法后会中止信号,此时signal.abortedtrue

代码语言:javascript
复制
// 监听 abort 事件
signal.addEventListener('abort', () => {
  console.log("信号中止!")
});

// 控制器中止信号
controller.abort(); 

console.log('是否中止:', signal.aborted); 

如上代码调用后会依次打印:

  1. 信号中止!
  2. 是否中止:true

在fetch中的应用

fetch API已经集成了AbortSignal

只需要将controller内的「信号对象」作为signal参数传给fetch

代码语言:javascript
复制
const controller = new AbortController();
fetch(url, {
  signal: controller.signal
});

当调用controller.abort()后,fetchpromise会变为AbortError DOMException reject

代码语言:javascript
复制
fetch('xxxx', {
  signal: controller.signal
}).then(() => {}, err => {
  if (err.name == 'AbortError') { 
    // 中止信号
  } else {
    // 其他错误
  }
})

可以在此时处理中止后的操作。

这里有个取消视频下载Demo[1],可以看看fetch如何配合AbortSignal实现取消下载

与任何异步操作结合

不仅是fetch,任何异步操作只要符合如下规范,都可以与AbortError集成:

  1. AbortSignal(信号对象)作为APIsignal参数传入
  2. 约定如果API返回的promise变为AbortError DOMException reject则代表操作被中止
  3. 如果signal.aborted === true则立刻让promise变为reject
  4. 观测AbortSignal状态的变化

如果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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-09-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 魔术师卡颂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • AbortSignal是什么
  • 在fetch中的应用
  • 与任何异步操作结合
  • 总结
    • 参考资料
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档