RxJS retryWhen未完成重试即提前抛异常问题求助(Angular12+RxJS6.4)
解决方案
问题分析
你当前的代码存在两个核心问题:
retryWhen中的take(this.retryCount)会在捕获到指定次数的错误后直接终止错误流,随后concatMap立即抛出异常,导致重试还没完成就触发错误回调。- 未处理成功响应中空字段触发重试的需求,当前逻辑只有HTTP错误才会进入重试流程。
修正后的代码实现
API调用部分
import { Observable, throwError } from 'rxjs'; import { delay, retryWhen, tap, scan, map } from 'rxjs/operators'; // ... delay = 5000; retryCount = 5; return this.httpClient.post('http://localhost:8080/info', JSON.stringify(data)) .pipe( // 检查响应中的空字段,存在则转为错误触发重试 map(response => { // 根据实际需求判断空字段,示例假设检查关键必填字段 if (!response?.requiredField || response.requiredField === '') { throw new Error('Response contains empty required field'); } return response; }), // 配置重试逻辑 retryWhen(errors => errors.pipe( // 累计重试次数,达到上限则抛出最终错误 scan((count, error) => { if (count >= this.retryCount) { throw error; } console.log(`Retrying (${count + 1}/${this.retryCount})`); return count + 1; }, 0), // 每次重试前延迟指定时长 delay(this.delay) ) ) );
响应处理部分
this.searchService.searchInfo(param1, param2).subscribe({ next: (data) => this.handleSuccessResponse(data), error: (error) => handleErrorResponse(error) }); handleSuccessResponse(data) { // 处理正常响应逻辑 } handleErrorResponse(error) { // 处理最终错误(重试耗尽或其他致命错误) console.error('Request failed after retries:', error); }
关键逻辑说明
- 空字段触发重试:通过
map操作符拦截成功响应,判断指定字段是否为空,若为空则主动抛出错误,让retryWhen捕获并触发重试流程。 - 重试生命周期控制:使用
scan操作符累计重试次数,当次数达到设定的retryCount时抛出最终错误,否则延迟后继续发起重试,确保完成所有重试后才触发错误回调。 - 移除错误的流控制:删掉原代码中导致提前终止的
take和concatMap组合,改用scan管理重试计数,避免重试未完成就抛出异常。
内容的提问来源于stack exchange,提问作者biswas
相关产品推荐
相关产品推荐

