最直接方式是用 promise.race 包装请求与定时 reject 的 promise,超时抛出统一 'timeout' 错误;但需配合 abortcontroller 真正中止 fetch,封装 timeout 工具函数并集成到统一请求层,设置默认超时、分类错误、结构化上报。

用 Promise.race 包装请求并统一抛出超时错误
最直接的方式是把原始请求 Promise 和一个定时 reject 的 Promise 一起交给 Promise.race() 竞速。谁先完成,就以谁的结果为准。超时 Promise 在指定毫秒后调用 reject(new Error('Timeout')),这样整个操作就会被中断并抛出可识别的错误。
- 封装成工具函数,例如
timeout(promise, ms),接收任意 Promise 和毫秒数 - 避免在
new Promise内部直接写setTimeout(...reject),必须用函数包裹防止立即执行 - 错误消息建议固定为
'Timeout'或使用自定义错误类(如class TimeoutError extends Error),便于后续instanceof判断
优先用 AbortController 真正中止 fetch 请求
单纯靠 Promise.race 只能“丢弃结果”,但底层网络请求仍在运行,可能浪费带宽和连接资源。现代 fetch 支持 AbortSignal,配合 AbortController 可真正终止请求。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 创建
const controller = new AbortController(),把controller.signal传入fetch的signal选项 - 用
setTimeout(() => controller.abort(), ms)触发中止 - 捕获错误时区分
err.name === 'AbortError',而不是只看 message 字符串 - 记得在成功或失败后调用
clearTimeout清理定时器,防止内存泄漏
在统一请求函数中集成超时与错误分类
不要把超时逻辑散落在每个 await 前。应在团队共用的请求封装层(如 api.get()、api.post())里内置超时控制,并按场景归类错误。
- 默认设置合理超时时间(如 GET 5s、POST 10s),允许调用方通过
{ timeout: 8000 }覆盖 - 对非 2xx 响应主动抛出
ApiError,包含status、code(如'HTTP_503')、level: 'error' - 超时错误统一标记
code: 'REQUEST_TIMEOUT',方便监控系统过滤和告警 - 所有错误都附加
context字段,例如{ url: '/api/order', method: 'POST' }
顶层兜底 + 错误上报闭环
即使封装再完善,也不能保证每个 await 都被 try/catch 包裹。需要建立最后一道防线。
- 全局监听
window.addEventListener('unhandledrejection'),捕获漏网的 Promise reject - 在回调中判断错误是否为超时类型,打上
isTimeout: true标记再上报 - 结合前端监控平台(如 Sentry),将
code、level、context作为结构化字段上传 - 对高频超时接口,自动触发告警并关联网络质量、CDN 状态等外部指标
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










