You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);
}

关键逻辑说明

  1. 空字段触发重试:通过 map 操作符拦截成功响应,判断指定字段是否为空,若为空则主动抛出错误,让 retryWhen 捕获并触发重试流程。
  2. 重试生命周期控制:使用 scan 操作符累计重试次数,当次数达到设定的 retryCount 时抛出最终错误,否则延迟后继续发起重试,确保完成所有重试后才触发错误回调。
  3. 移除错误的流控制:删掉原代码中导致提前终止的 take 和 concatMap 组合,改用 scan 管理重试计数,避免重试未完成就抛出异常。

内容的提问来源于stack exchange,提问作者biswas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 08:54:23