【问题标题】:How to resume RxJs Observable Interval on Error如何在错误时恢复 RxJs Observable Interval
【发布时间】:2017-07-03 16:02:39
【问题描述】:

我正在合并两个 Observable。 第一个在初始化时获取当前温度。 第二个以特定间隔轮询 API。 如果 Api 调用失败,则 Observable 间隔不会恢复。

我怎样才能恢复它?

getCurrentTemp(): Observable<number> {
    return this.http.get(this.environmentService.getTemperatureUrl())
      .map((res: Response) => res.json())
      .switchMap(() => res.temp);
  }

  pollCurrentTemperature(): Subscription {
    const temp$ = this.getCurrentTemp();
    const tempInterval$ = Observable
      .interval(3000)
      .flatMap(() => this.getCurrentTemp());

    return temp$
      .take(1)
      .merge(tempInterval$)
      .subscribe((temp: number) => {
        console.log('temp', temp);
      }, (err) => {
        console.log('error', err);
        // When the api fails my interval does not resume. How can I retry it?
      });
  }

有什么想法吗?类型

【问题讨论】:

标签: rxjs observable


【解决方案1】:

使用catch

Catch:通过继续没有错误的序列从 onError 通知中恢复

getCurrentTemp(): Observable<number> {
    return this.http.get(this.environmentService.getTemperatureUrl())
      .map((res: Response) => res.json())
      .catch(error => {
          console.log('Error occured');
          return Observable.empty();
       });
      .switchMap(() => res.temp);
}

它将捕获错误并在其位置静默返回empty observable。实际上,switchmap 将静默跳过失败的 api 调用,因为它不会为空的 observable 发出。

当然,您可以在错误时使用另一种行为,但您需要捕获它以避免您面临的问题。

【讨论】:

    【解决方案2】:

    使用 http 状态代码,您可以仅在其为 200 时检索可观察对象:

     getCurrentTemp(): Observable<number> {
        return Observable.from(
          [
            { value: 1, status: 200 },
            { value: 2, status: 200 },
            { value: 3, status: 200 },
            { value: 4, status: 200 },
            { value: 5, status: 200 },
            { value: 6, status: 400 }])
          .switchMap((x: any) => {
            if (x.status === 200) {
              return Observable.of(x.value);
            }
            return Observable.onErrorResumeNext();
          });
      }
    
      pollCurrentTemperature(): Subscription {
        const temp$ = this.getCurrentTemp();
        const tempInterval$ = Observable
          .interval(3000)
          .flatMap(() => this.getCurrentTemp());
    
        return temp$
          .take(1)
          .merge(tempInterval$)
          .subscribe((temp: number) => {
            console.log('temp', temp);
          }, (err) => {
            console.log('error', err);
            // When the api fails my interval does not resume. How can I retry it?
          });
      }

    重要的是这个 return Observable.onErrorResumeNext();

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-28
      • 2017-09-04
      • 2017-07-27
      • 2019-08-19
      • 1970-01-01
      • 1970-01-01
      • 2016-10-04
      • 1970-01-01
      相关资源
      最近更新 更多