rxjs复杂网络请求重试需用retrywhen+scan+delaywhen+takewhile组合实现指数退避、错误分类与次数限制,区分可重试(0/5xx/网络异常)与不可重试错误(401/404),401需先刷新token再重发,并通过takeuntil响应取消信号防泄漏。

RxJS 实现复杂网络请求重试流,核心在于组合 retryWhen、delay、scan、takeWhile 和错误分类逻辑,而非简单调用 retry(3)。关键是要控制重试时机、次数、退避策略,并区分可重试与不可重试错误。
用 retryWhen + scan 实现带指数退避的可控重试
直接使用 retry(3) 无法自定义延迟时间或判断错误类型。retryWhen 接收一个“错误通知流”,你可以在其中决定何时重试、是否放弃。
- 用
scan累计失败次数,避免闭包状态丢失 - 用
delay实现逐次加长的等待(如 100ms → 400ms → 1600ms) - 用
takeWhile限制最大重试次数,防止无限循环
示例:
const apiCall$ = ajax.getJSON('/api/data');apiCall$.pipe(
retryWhen(errors$ =>
errors$.pipe(
scan((acc, err) => ({ count: acc.count + 1, error: err }), { count: 0, error: null }),
takeWhile(({ count }) => count
delayWhen(({ count }) => timer(Math.pow(2, count) * 100)) // 指数退避
)
)
);
按错误类型分流:只对特定错误重试
网络超时、502/503 可重试;401(未授权)、404(不存在)通常不该重试。需在 retryWhen 中检查错误详情。
- 从
ajax错误中提取status或xhr.status - 对 0(断网)、5xx、网络异常(
TypeError: Failed to fetch)放行重试 - 遇到 401 时可先刷新 token,再重发请求(需配合
concatMap或switchMap)
示例判断逻辑:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
errors$.pipe(
filter(err => {
const status = err.xhr?.status ?? 0;
return status === 0 || status >= 500 || /network|fetch/.test(err.message);
}),
// 后续接 scan + delayWhen ...
)
)
结合 token 刷新的条件重试(带状态管理)
当请求返回 401 时,不能直接重试,而应先调用 refreshToken$,成功后再重发原请求。这需要将原始请求“缓存”并延迟执行。
- 用
catchError拦截 401,发起 token 刷新流 - 刷新成功后,用
concatMap重新发起原始请求 - 其他错误(如刷新失败)才走常规重试逻辑
结构示意:
authApiCall$.pipe(catchError(err =>
if (err.status === 401) {
return refreshToken$.pipe(concatMap(() => authApiCall$));
} else {
return throwError(() => err); // 交给 retryWhen 处理
}
}),
retryWhen(/* 只处理非 401 的错误 */)
)
取消重试:用户离开页面或主动中止
重试过程必须响应取消信号,否则可能在组件卸载后仍尝试请求,造成内存泄漏或状态错乱。
- 将
retryWhen内部的timer或delayWhen与takeUntil结合 - 监听路由变化(如 Angular 的
ActivatedRoute.url)或 React 的useEffect cleanup函数生成的 Subject - 确保所有内部定时器都受控于同一个取消流
例如:
const cancel$ = new Subject// ... 在组件销毁时:cancel$.next(); cancel$.complete();
retryWhen(errors$ =>
errors$.pipe(
scan(...),
takeWhile(...),
delayWhen(...),
takeUntil(cancel$) // 关键:中断重试计划
)
)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










