封装支持取消、重试、超时的通用网络请求库,需用 fetch + abortcontroller 实现真正可取消请求,配合 settimeout 模拟超时,按错误类型智能重试(限3次+指数退避),并统一返回结构与分层错误。

封装一个支持取消、重试、超时控制的通用网络请求库,关键在于把三件事解耦又协同:每次请求独立可控(取消)、失败后智能决策是否重试(重试)、不卡死也不无限等(超时)。不需要引入 axios 也能做到,用原生 fetch + AbortController 就足够轻量、可靠。
用 AbortController 实现真正可取消的请求
取消不是“假装没发”,而是让浏览器中止正在进行的网络连接。必须为每一次 fetch 创建新的 AbortController,不能复用同一个实例:
- 每次调用请求函数时,内部新建
const controller = new AbortController() - 把
controller.signal传给fetch(..., { signal }) - 暴露
cancel()方法,调用时执行controller.abort() - 在重试逻辑里,若已 cancel,则不再发起下一次,直接 reject
超时不是靠 fetch 自带,而是主动中断
fetch 本身不支持 timeout 参数,得靠 setTimeout 配合 AbortController 模拟:
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
- 发起请求前,设置
setTimeout(() => controller.abort(), timeoutMs) - 请求成功或失败后,记得
clearTimeout避免内存泄漏 - 捕获
AbortError(如err.name === 'AbortError')并归类为超时错误 - 超时错误属于可重试类型,但需和业务逻辑配合——比如 POST 提交订单就不该自动重试
重试要有条件、有节制、有退避
盲目重试等于制造压力,要判断错误类型、控制次数、拉长间隔:
- 只对可恢复错误重试:网络中断(
TypeError)、服务端错误(5xx)、超时(AbortError) - 明确不重试:客户端错误(
4xx,如 401/403/404),这类错重试无意义 - 默认最多 3 次,延迟用指数退避:100ms → 200ms → 400ms(可加随机抖动防雪崩)
- 每次重试都生成新请求参数(尤其含 timestamp 或 token 时),避免缓存或过期问题
返回结构统一,错误分层清晰
上层业务不该反复写 if (!res.ok) 或手动 res.json():
- 成功时返回标准化对象:
{ data, status, headers, url } - 失败时抛出自定义错误,含字段:
status(HTTP 状态码)、message(原因)、retryCount(已重试几次)、originalError(原始错误) - 网络层错误(断网)、HTTP 层错误(500)、业务层错误(
{ code: 1001, msg: "余额不足" })逐层区分,方便全局拦截处理










