首页 > 解决方案 > 延迟 n 秒重试轮询服务

问题描述

private pollSubscriptions: Subscription;
private defaultPollTime: number = 2000;
constructor(
    private http: HttpClient,
) {
    this.pollSubscriptions = new Subscription();
}

pollRequest<T>(
    url: string,
    updateStatus: any,
    pollWhileCondition: Function,
    onPollingSuccessCallback?: Function,
    timer = this.defaultPollTime
) {
    this.pollSubscriptions.add(timer(0, 2000).pipe(
        switchMap(() => this.http.get<T>(url).pipe(
            catchError((error: any) => empty()))),
        tap(updateStatus),
        takeWhile(data => pollWhileCondition(data)))
        .subscribe());
}

ngOnDestroy(): void {
    this.pollSubscriptions.unsubscribe();
}

我可以同时轮询多个 url。但是如何增强当前的功能,以便满足以下要求:

  1. 如果被轮询的 url 失败,那么我们如何以 3(n) 秒的延迟重试轮询 url 3 次?
  2. 我们如何在被轮询的 url 上添加不同的运算符?

仍然没有解决方案

提前致谢

标签: javascriptangularrxjsreactive-programmingrxjs6

解决方案


希望这有帮助..

有几件事:

  1. 如果您希望所有民意调查同时发生,您可能希望使用共享计时器进行民意调查。所以我在pollWhen下面添加了一个属性。
  2. 您正在寻找retryWhen,这是一个非常难以理解的运算符,但基本上它的工作原理是这样的:当您订阅时,它会调用您传递给它的函数,并带有可观察到的潜在错误,当发出错误时,您应该将其清理为“下一个”值以重试,立即完成(例如空)以安静地完成,或错误(例如 throwError)以错误杀死可观察对象。
class Component() {
  /** ticks every 10 seconds */
  pollWhen = timer(0, 10000)
    .pipe(share());

  private pollSubscriptions: Subscription;

  constructor(
      private http: HttpClient,
  ) {
      this.pollSubscriptions = new Subscription();
  }

  pollRequest<T>(
      url: string,
      updateStatus: any,
      pollWhileCondition: Function,
      onPollingSuccessCallback?: Function,
      timer = this.defaultPollTime
  ) {
      this.pollSubscriptions.add(this.pollWhen.pipe(
      switchMap(() =>
        this.http.get<T>(url).pipe(
          // Setup retries
          retryWhen(
            errors => errors.switchMap(
              // if more than 3 retries,
              // stop retrying quietly
              (_, i) => i < 3
                ? timer(1000)
                : EMPTY
            )
          )
        )
      ),
      tap(updateStatus),
      takeWhile(pollWhileCondition)
    ).subscribe());
  }

  ngOnDestroy(): void {
    this.pollSubscriptions.unsubscribe();
  }
}

推荐阅读