网络请求重试需区分异常类型:fetch未发出或中断进catch可重试;res.ok为false时,500–599可重试,400–499(除408、429)不重试;超时和json解析失败也统一进catch处理。

在网络请求异常时用条件分支控制重试,关键不是“有没有异常”,而是“什么类型的异常该重试”。JavaScript 的 fetch 本身不抛出 HTTP 状态码错误(如 500、404),只在真正网络失败或被中止时才进 catch;而成功响应但状态异常(比如 res.status === 503)必须手动判断并触发重试逻辑。这就要求你在 try 块里做两层判断:先看是否拿到响应,再看响应是否可用。
区分网络异常和业务异常,分别走不同分支
网络异常(如断网、DNS 失败、AbortError)属于临时性问题,适合立即重试;而 400、401、404 这类状态码通常表示客户端问题,重试无意义。因此条件分支要明确分开处理:
-
进
catch分支:说明 fetch 根本没发出或中途失败(TypeError: Failed to fetch、AbortError),这类一律视为可重试 -
进
try分支但!res.ok:需进一步检查res.status—— 若是500–599,归入可重试;若是400–499(除 408、429),直接返回不重试 -
成功响应但数据格式不符(如 JSON 解析失败),也应主动
throw,统一进catch流程,避免漏判
用 if-else 控制重试次数和退出路径
不能依赖 while (true) 或无限递归。每次重试前用计数器判断是否已达上限,用 if 明确写出“该不该继续”:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 当前尝试次数
→ 执行指数退避后继续下一轮 - 当前是最后一次尝试 → 不再等待,直接
throw err让上层处理 - 响应成功(
res.ok)→ 立即return res,跳出整个流程
结合 AbortController 实现超时可控的重试
原生 fetch 没有超时机制,容易卡住。用 AbortController 主动中断 + 条件分支判断中断原因:
- 创建
controller = new AbortController(),把signal传入fetch选项 - 用
setTimeout(() => controller.abort(), timeoutMs)设置超时 - 在
catch中检查err.name === 'AbortError'→ 视为超时,可重试 - 若
err.name === 'TypeError'且消息含"aborted",同样归入可重试分支
实际代码中条件分支的典型写法
下面是一个带超时、状态码判断和计数控制的简化结构,重点看 if/else 如何串联逻辑:
for (let i = 0; i const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000);
try {
const res = await fetch(url, { ...options, signal: controller.signal });
clearTimeout(timeoutId);
if (res.ok) return res;
if (res.status >= 500 && res.status throw new Error(`HTTP ${res.status}`);
}
return res;
} catch (err) {
if (i === maxRetries) throw err;
if (err.name === 'AbortError' || err.name === 'TypeError') {
await new Promise(r => setTimeout(r, 1000 * Math.pow(2, i)));
} else {
throw err;
}
}
}
}
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










