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

如何用RxJS实现API1响应后延迟5秒调用API2且初始调用无需等待

问题

在API(1)请求得到响应后调用API(2),要求API(2)每次调用间隔5秒,且当指定条件满足时停止调用。目前已有实现代码可正常运行,但现在希望调整为:API(2)首次调用无需等待,后续调用延迟5秒执行。现有代码如下:

const iterator = new BehaviorSubject<number>(0);

return this.api1.post(data).pipe(
  concatMap((res) =>
    iterator.pipe(
      mergeMap((i) =>
        this.api2
          .get(res?.id)
          .pipe(
            tap((result: any) => {
              if (
                result.info?.count <= 7 &&
                result.done === false &&
                !isNotNullOrUndefined(result.error)
              ) {
                iterator.next(i + 1);
              } else {
                const errorsDetails = {
                  message: result.info?.stage_message,
                  detail: result.error?.details,
                };
                this.showToastError(errorsDetails, false);
              }
            }),
            takeWhile(
              (d) =>
                d.info?.count <= 7 &&
                d.done === false &&
                !isNotNullOrUndefined(d.error),
              true
            )
          )
      )
    )
  )
);

解决方案

要实现「首次调用无延迟,后续每次间隔5秒」的效果,只需针对iterator的非首次发射添加延迟逻辑即可,具体修改如下:

修改点说明

  • 借助iterator的发射值i判断是否为首次调用:初始值0对应首次请求,后续值>=1对应延迟请求
  • 首次调用直接执行API请求,后续调用先通过timer(5000)等待5秒,再发起API请求

修改后的完整代码

const iterator = new BehaviorSubject<number>(0);

return this.api1.post(data).pipe(
  concatMap((res) =>
    iterator.pipe(
      mergeMap((i) => 
        // 首次调用(i=0)直接请求,后续先延迟5秒
        i === 0 
          ? this.api2.get(res?.id)
          : timer(5000).pipe(switchMap(() => this.api2.get(res?.id)))
      ),
      tap((result: any) => {
        if (
          result.info?.count <= 7 &&
          result.done === false &&
          !isNotNullOrUndefined(result.error)
        ) {
          iterator.next(iterator.value + 1);
        } else {
          const errorsDetails = {
            message: result.info?.stage_message,
            detail: result.error?.details,
          };
          this.showToastError(errorsDetails, false);
        }
      }),
      takeWhile(
        (d) =>
          d.info?.count <= 7 &&
          d.done === false &&
          !isNotNullOrUndefined(d.error),
        true
      )
    )
  )
);

额外优化说明

  • 原代码中iterator.next(i + 1)替换为iterator.next(iterator.value + 1),避免依赖闭包中的i值,逻辑更直观
  • 也可以用mergeMap的第二个参数index判断:index === 0时直接请求,效果完全一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 10:45:34