await 本身不提供中断能力,需通过 abortcontroller 主动拒绝 promise 实现中断;支持 signal 的 api(如 fetch)可自动响应 abort,普通 promise 需手动监听或检查 signal.aborted;结合 timeout 与 abort 可兼顾超时控制与请求取消,且应区分 aborterror 与业务异常分别处理。

await 本身不提供中断能力,它只是等待 Promise 完成。要实现“中断”,必须让 await 等待的 Promise 主动拒绝(reject),并由开发者控制这个拒绝时机——核心手段是 AbortController 和 手动信号检查。
用 AbortController 让 await 拒绝
这是最标准、浏览器原生支持的方式。关键不是“中断 await”,而是让 await 的 Promise 因 abort 而 reject:
- 创建控制器:
const controller = new AbortController() - 把
controller.signal传给支持中断的 API,比如fetch(url, { signal }) - 调用
controller.abort()后,fetch 会立刻以AbortError拒绝,await 就会跳出并进入 catch 块 - 注意:普通 Promise(如
new Promise(r => setTimeout(r, 1000)))默认不响应 signal,需手动监听:signal.addEventListener('abort', () => reject(new DOMException('Aborted', 'AbortError')))
在 await 前主动检查是否该中止
适合自定义长逻辑(如轮询、分块处理),避免无谓等待:
- 把
AbortSignal作为参数传入 async 函数 - 在关键节点(比如循环开始前、await 前)插入判断:
if (signal.aborted) throw new DOMException('Aborted', 'AbortError') - 这样即使还没走到 await,也能提前退出,减少资源浪费
组合超时与中断,增强健壮性
单靠 abort 不解决网络卡死问题;单靠 timeout 又不能真正终止请求。两者结合才是稳妥方案:
- 用
Promise.race([fetch(...), timeoutPromise])控制等待时长 - 同时把
AbortController的 signal 传给 fetch,确保超时后请求也被取消 - 封装成工具函数更清晰,例如:
async function withTimeout(promise, ms, signal?) { ... },内部自动创建 controller 并统一管理
错误处理要区分中断与业务异常
中断产生的错误(AbortError)和接口报错(如 404、500)性质不同,应分类响应:
- catch 中检查
err.name === 'AbortError',可静默忽略或重置 UI 状态 - 对网络错误或服务异常,记录日志、提示用户、触发重试
- 避免所有错误都弹“请求失败”,掩盖真实原因










