前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库AbortController 取消 fetch 流式请求实践
AIAI 全栈流式交互

如何用 AbortController 正确取消一个正在进行的 fetch 流式请求?

使用 AbortController 的 abort() 可中止 fetch 流式请求,但需在 abort 事件中主动调用 reader.cancel() 并捕获 AbortError 来正确释放底层连接。

前端进阶之旅 · 一题精讲更新于 2026.09.05
AI 全栈#流式交互#流处理
先看核心答案
理解线索

AbortController 取消流的关键点

  1. signal 传入 fetchfetch 接收 signal 后,取消时请求会被终止
  2. abort 触发 reject正在读取的 read() 会抛出 AbortError
  3. cancel 释放资源调用 reader.cancel() 解除锁并关闭底层连接

只有当流尚未自然结束时 abort 才真正起作用;已完成的流调用 abort 无副作用。

核心回答

先记住这个答案

创建一个 AbortController,将 signal 传入 fetch。当获得 response.body 的 reader 后,监听 signal 的 abort 事件:调用 reader.cancel() 使读取循环退出,并捕获 AbortError 进行资源清理。在 async 读取函数中,abort 会导致 reader.read() 立即 reject,因此需在 catch 中判断错误类型,区分主动取消与网络错误。

  • abort 后 reader.read() 会 reject AbortError
  • 主动调用 reader.cancel() 可释放锁与连接
  • 捕获 AbortError 并做差异处理

abort 信号如何中断正在进行的读取

当调用 controller.abort() 时,fetch 返回的 Promise 会以 AbortError 拒绝。若此时已通过 response.body.getReader() 获得 reader,那么正在等待的 reader.read() 也会被拒绝,同样抛出 AbortError。这是因为 abort 会向底层网络层发出取消指令,使流进入错误状态。因此,代码内需要在 catch 中区分此错误,避免将其视为普通网络故障。

但仅依赖 read() 的异常是不够的,规范并没有要求浏览器在 abort 时自动调用 reader.cancel()。为使流对象上的锁被立即释放,应在 signal 的 abort 事件回调中显式调用 reader.cancel()。cancel() 返回一个 Promise,可忽略结果,但它会触发底层关闭流程。如果未调用 cancel(),reader 可能保持锁定,导致后续无法重新绑定同一响应数据流,并延长连接释放时间。

带停止按钮的流式聊天补全

假设聊天页面有一个“停止生成”按钮。用户点击发送后,前端创建 AbortController,将 signal 传给 fetch 并发起流式请求。读取循环把每个 value 解码成文本并追加到消息框。按钮点击事件调用 controller.abort(),同时更新界面状态为“已停止”。

为确保循环及时退出,需在 abort 事件里调用 reader.cancel()。虽然 abort 会使挂起的 read() 被拒绝,但显式调用 cancel() 可确保读锁被立即释放,减少实现差异带来的资源滞留。在 catch 中判断 error.name === 'AbortError' 后,执行清理如隐藏加载指示、释放引用。注意若用户快速连点,应禁用按钮或每次重新生成新的 AbortController,避免取消掉后续请求。

abort 的有效条件与常见失败原因

如果响应已经读取完毕(read() 返回 {done:true}),再调用 abort() 不会引发任何事件,也不会影响已收到的内容。如果服务端已经发送了完整响应但客户端尚未读完,abort 会中断连接,但可能已产生计费,这是取消的固有代价。abort 无法撤销已暴露给用户的文本。

多请求并发时,每个请求必须持有独立的 AbortController。若多个请求复用同一个 signal,取消一个会误杀全部。另外,abort() 只能触发一次,多次调用无效。如果 fetch 因网络错误而失败,abort 不会重复触发,此时应单独处理。对于已取消的请求,不能再复用该 response 对象,需要重新发起请求。

回答前,多想一步

容易答错的地方

只调用 abort 不处理 reader
很多实现以为 abort() 会自动关闭流,但实际只让 read() 抛出 AbortError。若不调用 reader.cancel(),底层套接字可能不会立即关闭,且 reader 锁未释放。应在 abort 监听器中主动 cancel 并捕获异常。
把 AbortError 当普通错误处理
有的代码 catch 里将所有错误都按网络问题弹窗提示,导致用户点击停止后出现错误提示。应通过 error.name === 'AbortError' 区分主动取消,静默处理并进入停止状态。否则会造成困扰且无法正确恢复。
试着用自己的话回答

面试官还会怎么问?

取消后能否继续从断点续传?

不能。fetch 的流式响应不支持续传,信号中断后连接已关闭。若需恢复,应保存已显示的文本,用新请求模拟继续,或使用 SDK 内置的恢复模式。

如果 abort 发生在 read() 返回之后但未处理前,会怎样?

若 abort 在两次 read 之间,下一次 read() 会立刻 reject AbortError;若 abort 在 read 成功返回后,Promise 已解析,abort 不会影响该次结果。

AbortController 可以被多次 abort 吗?

不能。abort() 方法只触发一次事件,后续调用会被忽略。若需再次取消同一请求,需创建新的 AbortController。

从一道题,走向一组知识

把知识连起来

流式交互

Anthropic Messages API 流式响应中 message_start、content_block_delta、message_stop 等事件各自携带什么信息?

同属「流式交互」专题,接着看 Anthropic 流式事件类型 message_start content_block_delta 在具体场景中的处理方式。

流式交互

在 AI 聊天场景中,Server-Sent Events 和 WebSocket 该如何选型?

同属「流式交互」专题,接着看 SSE 与 WebSocket 在 AI 流式对话中的选型对比 在具体场景中的处理方式。

参考资料

  • Streaming messages - Claude Platform Docs

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. abort 信号如何中断正在进行的读取
  3. 带停止按钮的流式聊天补全
  4. abort 的有效条件与常见失败原因
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑