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

Angular RxJS递归调用API直至状态为true的问题排查

RxJS循环检查文件状态问题修复

原代码的核心问题是循环检查文件状态的逻辑存在漏洞,导致只执行一次检查就进入后续流程。以下是修复后的代码及问题解析:

修复后的代码

this.homeService.auth().pipe(
  switchMap(authToken => {
    return this.homeService.uploadFile(this.masterFile);
  }),
  // 循环检查文件状态
  switchMap(fileId => {
    let retries = 0; // 将重试计数器放在内部,避免全局污染
    return this.homeService.fileStatus(fileId).pipe(
      expand(status => {
        // 状态为true或重试次数耗尽时,停止扩展
        if (status === true || retries >= 50) {
          return EMPTY;
        }
        retries++;
        // 延迟2秒后再次调用状态检查接口
        return timer(2000).pipe(
          switchMap(() => this.homeService.fileStatus(fileId))
        );
      }),
      // 持续接收值直到状态为true或重试耗尽,true参数确保最后一个值被发出
      takeWhile(status => status === false && retries < 50, true),
      // 取最后一个值,确保只有最终状态被传递到下一个流程
      last(),
      catchError(() => {
        throw new Error('Failed to confirm upload status after 50 retries');
      })
    );
  }),
  switchMap((status: boolean) => {
    if (status === true) {
      return this.processFurther();
    }
    // 状态为false时抛出错误,终止流程
    throw new Error('File upload did not complete successfully');
  })
).subscribe(response => {
  console.log('All done'); // 原代码里的console.lot是笔误,修正为console.log
}, error => {
  console.log('Error processing ', error);
});

关键修复点

  1. 重试计数器作用域:将retries声明在switchMap内部,避免全局变量导致的计数器异常,每次文件上传都会重置计数器。
  2. expand操作符逻辑修正:移除多余的of(status),直接通过timer(2000)实现延迟后重新调用状态接口,确保每次重试都是真实的接口请求。
  3. 添加last()操作符:确保只传递最终的状态值(true或重试耗尽后的结果)到下一个switchMap,避免中间状态干扰后续流程。
  4. 修正笔误:原代码中的console.lot改为console.log。
  5. 状态异常处理:当最终状态为false时主动抛出错误,避免流程静默终止。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 22:55:04