取消请求本身不会导致内存泄漏,真正危险的是取消后残留的引用链——如未清理的回调、未释放的闭包捕获或挂载在长生命周期对象上的 promise 处理器。

取消请求本身不会导致内存泄漏,真正危险的是取消后残留的引用链——比如未清理的回调、未释放的闭包捕获、或仍挂在全局/长生命周期对象上的 Promise 处理器。
避免 fetch / axios 取消后的引用滞留
现代浏览器原生 fetch 不支持直接取消,但可通过 AbortController 实现可控中断。关键不在“是否取消”,而在“取消后是否还持有不该持有的对象”。
- 使用
signal选项发起请求,abort()会中断网络传输,但不会自动清理你代码里对响应数据、组件实例或大数组的闭包引用 - 错误写法:在回调中直接使用
this.state或domRef.current,且未在 abort 后重置这些引用 - 正确做法:将请求相关状态(如 loading、data)封装为局部变量或受控状态,在 abort 触发时主动清空或标记失效
Promise 链中未处理的 .then/.catch 引用
即使请求被 abort,如果 Promise 已进入 pending 状态并挂载了 .then 回调,而该回调又闭包捕获了大型对象(如整个表单数据、图表实例),这些对象就会因回调未执行完而无法回收。
- 不要在 .then 中直接操作 this 或外部大变量;改用轻量标识(如 id)+ 后续按需查询
- 在 abort 后显式丢弃 Promise 引用:
pendingRequest = null,防止旧请求回调意外触发 - 避免链式调用中无条件保留上层作用域:用 IIFE 或函数参数解构隔离引用范围
第三方库(如 axios)取消后仍驻留拦截器或缓存
axios 的 CancelToken 已废弃,推荐统一用 AbortController。但要注意:
- 自定义请求拦截器若缓存了 config 或 headers 中的大对象(如 base64 图片字符串),需在 abort 后手动清理
- 响应拦截器中若将 response.data 存入全局 Map 或 WeakMap,应配合 signal 的 abort 事件同步删除条目
- 避免在拦截器中创建闭包引用组件实例(如 Vue 的
this或 React 的ref),改用传参方式传递必要上下文
React/Vue 组件卸载时的协同清理
请求取消必须和组件生命周期对齐。只 abort controller 不够,还要确保组件销毁后不再响应任何异步结果。
- React 中:在
useEffect清理函数里调用controller.abort(),同时设置标志位(如isMounted = false),在 .then 中检查该标志再更新 state - Vue 中:在
onBeforeUnmount中 abort,并清空ref持有的响应数据对象(responseData.value = null) - 禁止在已卸载组件中调用
setState或ref.value = ...,否则不仅泄漏,还会报错
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











