前端进阶之旅前端进阶之旅
  • 基础篇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 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库fetch 超时 AbortController setTimeout
浏览浏览器请求与通信 API

fetch 本身没有超时参数,如何实现一个请求超时控制?

fetch没有内置timeout选项,但可用AbortController配合setTimeout实现:新建controller,将signal传给fetch,定时器到点调用abort(),让fetch以AbortError被拒绝。

前端进阶之旅 · 一题精讲更新于 2026.09.05
浏览器#请求与通信 API
先看核心答案
理解线索

AbortController 中断机制

  1. signal传给fetch,实现中断消息传递
  2. abort()触发signal的abort事件并拒绝fetch
  3. 定时器setTimeout到点执行abort实现超时

同一个signal可复用,但超时场景通常只绑定一个请求。

核心回答

先记住这个答案

创建AbortController实例,得到signal后放入fetch的配置对象。然后设setTimeout,到指定时间就调用controller.abort()。abort会触发abort事件,fetch监听后取消网络请求并让Promise变成rejected,错误名称为AbortError。务必在请求成功或失败的finally中清除定时器,避免对已完成请求重复abort造成不必要的操作。

  • fetch无原生timeout,必须自实现
  • AbortController+setTimeout可中断请求
  • abort后Promise以AbortError被拒绝

机制:signal如何触发中止

fetch的请求配置支持signal选项,传入AbortSignal后,fetch内部会监听该signal的abort事件。一旦abort被触发,fetch就立即中止当前请求,并让Promise进入rejected状态,错误对象是名为AbortError的DOMException。因此,实现超时的思路就是让定时器去调用controller.abort()。

定时器必须在请求结束后清理。如果请求在时限内完成,不清除定时器会让它稍后触发abort,虽然对已完成的fetch没有实际作用,但浪费回调;如果超时先触发,则定时器已执行,无需再清。所以推荐在请求的then或catch中用clearTimeout,最好放进finally以保证无论哪种情况都执行清理。

场景:30秒超时中断上传

文件上传接口在弱网下可能长时间无响应。要求超过30秒就提示用户并放弃请求。实现上先创建AbortController,将signal传给fetch,再setTimeout设30秒。到点调用abort(),在catch中检查抛出的error.name是否等于'AbortError',若是则显示'上传超时',否则按网络错误处理。

要注意,即使调用abort,服务器端可能仍在接收文件,因为连接只被浏览器侧切断。所以接口应支持断点重传或幂等性,避免产生不完整数据。另外,请求若在30秒内成功,必须在成功处理中clearTimeout,阻止超时abort干扰后续逻辑。

失效条件与处理

AbortController的abort不能取消服务器端的操作,只能中断浏览器到服务器的连接。如果请求已经到达服务器,那么服务端仍会继续执行,甚至可能返回响应,但浏览器已放弃。还有,如果主线程被长期阻塞,setTimeout的回调可能不准时,造成超时时间延后。

处理措施:在catch中只对AbortError做超时提示,其他错误走常规分支,以精确区分;同时所有请求分支(成功、失败)都要清除定时器。若需要更严格的超时,可把定时器放在独立worker,但一般场景够用。另外,AbortController也可并发取消多个请求,但此场景只需一个。

回答前,多想一步

容易答错的地方

fetch自带timeout参数?
误区:以为fetch支持timeout配置。规范未提供,需要手动用AbortController实现。即使某些库扩展了选项,也不原生。
abort会撤销服务器处理?
错误理解:认为调用abort会阻止服务器端继续工作。实际上仅中断浏览器侧,服务器可能已处理请求。需要服务端支持取消或幂等。
试着用自己的话回答

面试官还会怎么问?

fetch超时和XHR的timeout有什么本质区别?

XHR有内置timeout属性,超时触发ontimeout事件;fetch需自造,abort后Promise以AbortError被拒绝,要在catch中靠name判断。

如何准确识别一个错误是AbortError?

在catch中检查error.name === 'AbortError'。也可用error instanceof DOMException判断,但name是最稳的。

同一个AbortController可以给多个fetch用吗?

可以,signal可传给多个fetch,调用abort会同时中断它们。适用于批量请求取消,但超时场景只绑一个更清晰。

从一道题,走向一组知识

把知识连起来

请求与通信 API

fetch 默认跨域请求为什么不带 Cookie,credentials 选项各取值有什么区别?

同属「请求与通信 API」专题,接着看 fetch credentials cookie same-origin include 在具体场景中的处理方式。

请求与通信 API

fetch 发送 POST 请求时,FormData 与 JSON body 在 Content-Type 和处理上有什么区别?

同属「请求与通信 API」专题,接着看 fetch POST FormData JSON Content-Type boundary 在具体场景中的处理方式。

参考资料

  • AbortController

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

本题目录
  1. 先记住这个答案
  2. 机制:signal如何触发中止
  3. 场景:30秒超时中断上传
  4. 失效条件与处理
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

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

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