核心是将“网络不可用”视为预期状态而非异常,通过abortsignal.timeout设确定性断点,分三级兜底(内存缓存→持久缓存→默认值),统一返回结构,并按环境能力隔离逻辑链。

在网络中断时提供友好的降级方案,核心不是“等断网再补救”,而是从请求发起前就设计好可退守的响应路径。关键在于把“网络不可用”视为一种预期状态,而非异常事件。
用 AbortSignal.timeout 做确定性断点,不依赖网络反馈
网络中断往往表现为无响应、连接被重置或 DNS 失败,这些不会立刻抛出错误,容易让界面卡住。应主动设超时:
- 用 AbortSignal.timeout(8000) 创建标准中断信号,比手动 setTimeout 更可靠
- 只用它触发降级判断,不把它当作“失败原因”——真正的失败来源要靠后续 err.name === 'AbortError' 显式确认
- 避免在 fetch 中直接传 signal 而不做降级准备,否则中断后 Promise 永远 pending
主请求失败后,先验 signal.aborted 再走 fallback
不能一 catch 就跳转降级,因为网络错误(如 502)、解析失败(JSON.parse 报错)和超时中断需区别对待:
- 在 catch 块中检查 signal?.aborted === true,双重确认是超时导致中断
- 只有确认是 abort 才启动降级链:缓存 → 默认值;其他错误可单独上报或重试
- 降级请求本身也要带自己的 timeout(比如 12s),防止 fallback 也卡死
构建三级数据来源,每层返回统一结构
用户感知不到“网络断了”,只看到内容依然可用——这靠分层兜底实现:
- 内存缓存:优先查 WeakMap 或 Map 中近期解析成功的数据,带 timestamp 校验是否过期
- 持久缓存:查 localStorage 或 IndexedDB,读取含 version 和 expires 字段的离线副本
- 默认值:缓存全失效时返回轻量结构(如 []、{ loading: false, items: [] }),并标记 source: "default-fallback"
- 所有分支返回统一对象:{ data, source: "network" | "cache" | "default-fallback", timestamp }
兼容旧环境时启用隔离逻辑链,不靠 polyfill 模拟
IE11 或 Android 4.4 等环境不支持 AbortController,强行 polyfill 会掩盖真实行为:
- 用 'signal' in AbortController.prototype 检测能力,决定走现代路径还是 legacy 路径
- legacy 路径用 xhr + setTimeout 实现粗粒度超时,并手动维护请求状态 map 防止重复提交
- 降级策略保持一致:同样走缓存→默认值,只是中断机制不同
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











