AbortSignal.timeout()提供开箱即用的超时控制,传入毫秒数生成自动abort信号,Chrome 109+等现代浏览器原生支持,语义清晰且无内存泄漏风险。

直接用 AbortSignal.timeout() 就能实现极简超时控制,不需要手动创建 AbortController、也不用管理定时器清理——它返回一个“开箱即用”的信号,到点自动 abort,语义清晰、无内存泄漏风险。
一步写死超时,5 行搞定
现代浏览器(Chrome 109+、Firefox 119+、Safari 17.4+)原生支持,调用方式极其简洁:
- 传入毫秒数,如
AbortSignal.timeout(3000),表示 3 秒后中断请求 - 直接作为
signal选项传给fetch() - 超时会抛出
DOMException,err.name === 'AbortError' - 无需
try/catch也能工作,但建议捕获以区分超时和其他错误 - 该信号是一次性的,不可复用,也不影响其他请求
正确捕获并区分超时场景
别把超时当异常处理。Abort 是可控的流程终止,不是系统崩溃:
- 在
catch中优先判断err.name === 'AbortError',走降级或重试逻辑 - 不要把所有
catch都统一上报为错误——用户点了取消或网络卡顿,不该触发告警 - 若用了
controller.abort(reason)自定义原因,就别依赖name判断,改用signal.aborted或signal.reason
兼容老浏览器的轻量降级
如果需支持 Chrome 108 或更早版本,只需加一层检测:
- 检查
typeof AbortSignal.timeout === 'function' - 不支持时,用
AbortController + setTimeout模拟,注意在 fetch 完成后调用clearTimeout - 避免混用:已有手动
AbortController(如用于用户取消)时,不要和timeout()的 signal 合并使用,容易语义混乱
超时不是终点,而是控制起点
AbortSignal.timeout() 本身只管“时间到了就停”,但它可以轻松串联其他能力:
- 配合
Promise.race()实现更灵活的裁决逻辑(比如同时竞争多个数据源) - 作为熔断器的基础组件:超时失败计入统计,触发状态切换
- 与重试策略组合时,每次重试都应生成新的 timeout 信号,避免复用已 abort 的 signal

















