abortcontroller 是浏览器原生信号控制器,通过 signal 可主动中止未完成的 fetch 请求,触发 aborterror 并拒绝 promise;signal 不可复用,需每次新建;react 中应在 useeffect 清理函数中调用 abort()。

AbortController 是什么,为什么能取消 fetch
AbortController 是浏览器原生提供的信号控制器,它生成的 signal 对象可被传给 fetch(),让请求在发出后仍能被主动中止。这不是“中断 TCP 连接”,而是让 fetch() 提前拒绝 Promise 并抛出 AbortError,后续逻辑可据此清理状态。
关键点:只有未完成的请求能被取消;已响应的 fetch() 不受影响;signal 一旦触发 abort(),不可重用。
基础用法:创建 controller 并传 signal 给 fetch
最简可行路径就是实例化 AbortController,取其 signal 属性,作为 fetch() 的 signal 选项:
const controller = new AbortController();
const signal = controller.signal;
fetch('/api/data', { signal })
.then(res => res.json())
.catch(err => {
if (err.name === 'AbortError') {
console.log('请求已被取消');
} else {
console.error('其他错误:', err);
}
});
// 取消请求
controller.abort();
注意:controller.abort() 可在任意时刻调用,包括请求发出后、响应返回前的任意时间点。
常见错误:signal 复用、controller 提前释放、未捕获 AbortError
这些是实际项目中最容易卡住的地方:
-
signal不能复用:一个signal被abort()后,再次传给另一个fetch()会立刻报错AbortError;每次新请求必须新建AbortController - 忘记清空引用:如果 controller 被闭包长期持有(比如在 React 组件 state 里),但组件已卸载,再调用
abort()虽不报错,却无意义;建议在组件销毁/离开页面时显式调用 - 没区分错误类型:
catch块里直接处理err而不检查err.name === 'AbortError',会导致取消被当成网络错误上报或重试 - 服务端仍可能处理完请求:取消只影响客户端 Promise,后端通常不受影响,需配合 idempotency key 或 cancel token 等机制协同
React 中安全取消请求的典型模式
函数组件里,最容易漏掉的是 useEffect 清理时机与 controller 生命周期不一致:
useEffect(() => {
const controller = new AbortController();
fetch('/api/search?q=test', { signal: controller.signal })
.then(res => res.json())
.then(data => setData(data))
.catch(err => {
if (err.name !== 'AbortError') {
setError(err);
}
});
return () => {
controller.abort(); // 组件卸载时取消
};
}, []);
重点:清理函数必须在 effect 返回时注册,且不能依赖异步回调中的 controller 引用(比如放在 setTimeout 里再 abort 就可能失效);同时确保 signal 确实传给了 fetch —— 漏写 { signal } 选项是最隐蔽的失败原因。
复杂点在于并发请求管理:多个搜索输入频繁触发,要保证只响应最后一次。这时候不能靠手动 abort 上一个 controller,而应统一用 Ref 记录最新 controller,并在每次新请求前 abort 当前持有的旧 controller。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











