AbortController 中止控制器
AbortController 是一个标准的浏览器 API,用于中止异步操作(如 fetch 请求、流等)。它提供了一种优雅的方式来取消正在进行的操作。
💡 此功能在 Web Workers 中可用,并且从 2019 年 3 月起在所有主流浏览器中得到广泛支持。
核心概念
AbortController 由两个核心部分组成:
- AbortController:控制器对象,用于发送中止信号
- AbortSignal:信号对象,用于与异步操作通信
基本用法
创建 AbortController
const controller = new AbortController();
const signal = controller.signal;中止 Fetch 请求
主要 API
AbortController 实例方法
abort(reason?)
- 中止与该控制器关联的异步操作
- 可选的
reason参数用于指定中止原因(任意 JavaScript 值) - 如果不指定,默认为
AbortErrorDOMException
controller.abort(); // 默认原因
controller.abort(new Error('用户取消操作')); // 自定义原因AbortController 实例属性
signal
- 返回一个 AbortSignal 对象
- 只读属性
- 用于与异步操作通信
AbortSignal 实例属性
aborted
- 布尔值,指示请求是否已被中止
- 只读属性
reason
- 返回中止原因(JavaScript 值)
- 在信号未中止时为
undefined - 只读属性
AbortSignal 静态方法
AbortSignal.abort(reason?)
- 返回一个已经中止的 AbortSignal 实例
- 用于需要立即中止的场景
AbortSignal.timeout(time)
- 返回一个在指定时间后自动中止的 AbortSignal
time参数为毫秒数- 超时后会抛出
TimeoutErrorDOMException - 自 2024 年 4 月起在主流浏览器中可用
AbortSignal.any(signals)
- 接受一个 AbortSignal 数组
- 返回一个新的 AbortSignal,当数组中任一信号中止时,该信号也会中止
- 用于组合多个中止条件
AbortSignal 实例方法
throwIfAborted()
- 如果信号已中止,则抛出中止原因
- 否则什么也不做
- 用于在代码中快速检查中止状态
AbortSignal 事件
abort 事件
- 当请求被中止时触发
- 可以通过
addEventListener或onabort属性监听
实际应用场景
场景 1:取消下载操作
场景 2:请求超时处理
场景 3:实现可中止的 Promise API
场景 4:组合多个中止条件
注意事项
⚠️
重要提示
- AbortSignal 只能使用一次,一旦中止后,不能重新使用
- 每次新的请求都应该创建新的 AbortController
- 中止操作是异步的,不会立即停止所有相关操作
- 超时基于活动时间而非经过时间,在挂起的 worker 或 bfcache 中会暂停
浏览器兼容性
- AbortController/AbortSignal 基础功能:2019 年 3 月起广泛支持
- AbortSignal.abort():2021 年 9 月起支持
- AbortSignal.timeout():2024 年 4 月起支持
- AbortSignal.any():较新的 API,请检查具体浏览器版本
相关资源
总结
AbortController 提供了一种标准化的方式来取消异步操作,特别适用于:
- 取消 fetch 请求
- 实现请求超时
- 用户主动取消操作
- 组件卸载时清理异步任务
- 实现可取消的自定义异步 API
通过合理使用 AbortController,可以提升应用的用户体验和资源利用效率。