abortcontroller 能真正中断挂起的 fetch 请求,但前提是请求尚未发出或仍处于网络传输中;一旦响应头已接收、响应体开始流式读取,中止操作就不再终止底层 tcp 连接(浏览器限制),但能立即停止 javascript 层的后续处理(如 response.json()、response.body.getreader() 等)。

AbortController 能真正中断挂起的 fetch 请求,但前提是请求尚未发出或仍处于网络传输中;一旦响应头已接收、响应体开始流式读取,中止操作就不再终止底层 TCP 连接(浏览器限制),但能立即停止 JavaScript 层的后续处理(如 response.json()、response.body.getReader() 等)。
创建并关联 AbortController
新建控制器,把它的 signal 传给 fetch 选项:
const controller = new AbortController();
const signal = controller.signal;
fetch('/api/data', { signal })
.then(response => response.json())
.catch(err => {
if (err.name === 'AbortError') {
console.log('请求被主动取消');
} else {
console.error('其他错误:', err);
}
});
调用 abort() 触发中止
在任意时机(比如用户点击取消、组件卸载、超时)调用 controller.abort():
- 若请求还没发出(DNS 解析、TCP 握手阶段),连接会被直接放弃
- 若请求已发出但服务端还没返回响应头,浏览器会发送 RST 包或关闭 socket(行为因浏览器和协议而异,但效果是连接终止)
- 若响应头已到达、正在接收响应体,
abort()会让ReadableStream立即进入closed或errored状态,后续reader.read()返回{ done: true }或抛出AbortError
注意流式响应的特殊处理
对 response.body 手动读取时,必须监听 signal 并检查中止状态,否则可能漏掉中断:
const reader = response.body.getReader();
signal.addEventListener('abort', () => {
reader.cancel().catch(() => {}); // 主动取消 reader
});
while (true) {
const { done, value } = await reader.read();
if (done) break;
// 处理 chunk
}
更稳妥的方式是将 signal 直接传给 reader.read()(Chrome 126+、Firefox 128+ 支持):
const { done, value } = await reader.read({ signal });
避免内存泄漏:及时清理引用
AbortController 本身不自动销毁,需确保无外部引用。常见做法:
- 在 React 中,
useEffect清理函数里调用controller.abort() - 手动发起请求时,保存 controller 实例,在业务逻辑结束(如页面跳转、弹窗关闭)时显式 abort
- 不要重复复用同一个 controller —— 每次新请求应新建 controller
不复杂但容易忽略:AbortController 的中止能力依赖浏览器实现和网络栈状态,它无法强制杀掉已被系统缓存的连接或绕过代理/CDN 的中间缓冲,但它是在 Web 标准下最可靠、最通用的前端请求取消机制。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











