【问题标题】:Run method every 5 seconds related on status与状态相关的每 5 秒运行一次方法
【发布时间】:2021-10-12 07:47:27
【问题描述】:

我在组件中有从后端获取数据并检查状态的方法

这里是

 getRecognitionById() {
    this.loaderService.show(null, true);

    this.vendorWebApiService
      .createRecognition(this.executiveChangeId)
      .pipe(take(1))
      .subscribe((res) => {
        this.vendorWebApiService
          .getRecognition(res.taskRequestId, this.executiveChangeId)
          .pipe(take(1))
          .subscribe((recognitionResponse) => {
            if (recognitionResponse.jobStatus === "completed") {
              this.recognitionData = recognitionResponse;
              this.getLatesFeedback();
            }
            if (recognitionResponse.jobStatus === "failed") {
              alert();
            } else {
              
            }
          });
      });
  }

在这部分我检查状态

 this.vendorWebApiService
      .getRecognition(res.taskRequestId, this.executiveChangeId)
      .pipe(take(1))
      .subscribe((recognitionResponse) => {
        if (recognitionResponse.jobStatus === "completed") {
          this.recognitionData = recognitionResponse;
          this.getLatesFeedback();
        }
        if (recognitionResponse.jobStatus === "failed") {
          alert();
        } else {

        }
      });

但是如果状态是另一个然后完成或失败的问题,我需要每 5 秒重新运行一次这个逻辑,所以每 5 秒我需要检查一次状态,并且在 10 次尝试后,我需要显示警报。

我需要如何重写我的代码来实现这个逻辑?

【问题讨论】:

  • 您似乎需要递归调用 api,这意味着您应该使用 expand 运算符。此外,您还需要根据您的jobStatus 设置takeUntil/takeWhile,以便您可以摆脱循环。这是一个示例:stackoverflow.com/questions/65957969/…

标签: javascript angular typescript


【解决方案1】:

你可以用 rxjs 做到这一点

    import { interval, Subject, Subscription } from 'rxjs';
    refresher$: Observable<number>;
    refreshSub: Subscription;
    jobStatus: string = "init"
    checkCount = 0

    checkStatus() {
      this.checkCount++
      this.vendorWebApiService
        .getRecognition(res.taskRequestId, this.executiveChangeId)
        .pipe(take(1))
        .subscribe((recognitionResponse) => {
          jobStatus = recognitionResponse.jobStatus
          this.recognitionData = recognitionResponse
          
        });
    }

    getRecognitionById() {
      this.loaderService.show(null, true);

      this.checkStatus()
   }

    this.refresher$ = interval(5000); // every5 sec
    this.refreshSub = this.refresher$.subscribe(() => {
      this.checkStatus()
      if (this.jobStatus === 'completed') {
        this.getLatesFeedback();
      }
      if (this.jobStatus === 'failed') {
        alert()
      } else {
         if (this.checkCount == 10) {
            alert()
         }
      }

    });

【讨论】:

  • 我只需要运行`this.vendorWebApiService .getRecognition`和状态检查,而不是整个getRecognitionById请重新阅读帖子
  • 用服务调用做一个statusCheck()方法,在getRecognitionById中调用这个statusCheck()方法,在refreshSub旁边
  • 能否提供代码,怎么做?
  • 我正确理解了您的代码,您只需每 5 秒运行一次检查状态。我尝试实现的逻辑,如果状态与failedcompleted 不同,则再次运行getRecognition。如果状态未完成,则在 10 次尝试时,显示 alert()
  • 为了满足您的需求,您需要一个状态计数器,每次您检查服务器时都会进行迭代,在您的特定情况下,当它到达第二次迭代时,它应该执行警报,如果它没有成功。
【解决方案2】:

您可以通过这种方式实现:

  1. 定义一个计数器变量。

  2. 使用 5000 毫秒计时器定义一个间隔并将其引用到一个变量。

  3. 清除成功间隔。

  4. 失败时的重新运行间隔和counter &lt; 10 的计数器。

let counter = 0;
let interval = setInterval(() => {
  // ajax().next(() => {
  //   clearInterval(interval);
  // }).catch(() => {
  //   if (counter >= 10) {
  //     clearInterval(interval);
  //   } else {
  //     counter++;
  //   }
  // })
}, 5000);
  • 不要忘记在ngOnDestroy 中清除您的时间间隔,以防止您的应用在某些情况下崩溃。

【讨论】:

    【解决方案3】:

    使用 observables 你可以尝试这样的事情

      getRecognitionById() {
        //   this.loaderService.show(null, true);
        const ATTEMPT_COUNT = 10;
        const DELAY = 5000;
        this.vendorWebApiService
          .createRecognition(this.executiveChangeId)
          .pipe(take(1),
            mergeMap((res) => (
              this.vendorWebApiService
                .getRecognition(res.taskRequestId, this.executiveChangeId)
                .pipe(take(1),
              ))), map((recognitionResponse: any) => {
                if (recognitionResponse.jobStatus === "completed") {
                  this.recognitionData = recognitionResponse;
                  this.getLatesFeedback();
                }
                if (recognitionResponse.jobStatus === "failed") {
                  alert();
                } else {
                  throw { error: 'failed' };
                }
              }), retryWhen(errors => errors.pipe(
                scan((errorCount, err: any) => {
                  if (err.error === 'failed' || errorCount >= ATTEMPT_COUNT) {
                    // add code for alert after 10 retries
                  }
                  return errorCount + 1;
                }, 0),
                delay(DELAY),
              )));
      }
    

    【讨论】:

    • 得到了这个Property 'switchmap' does not exist on type
    • 只有在状态失败时才需要显示警报,在 else 块中,我需要再次重新运行逻辑
    • @EugeneSukh 我已经更新了代码,你能拿这个告诉我吗
    猜你喜欢
    • 2015-01-18
    • 2011-03-20
    • 2014-08-21
    • 2012-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-08
    相关资源
    最近更新 更多