rxjs publishReplay:重置错误

时间:2017-12-28 15:38:31

标签: angular rxjs rxjs5

我正在使用publishReplay(1).refCount()来缓存Angular5中的http请求。这很好 - 除了错误情况。

我正在吞咽并报告来自http源的异常,这就是我在下面的代码中传递Observable.of(undefined)的原因。在这种情况下,它当然会缓存未定义 - 但是跟随订阅者不应该获得该值,而是应该再次请求http资源,就像没有缓存一样。

我目前的代码:

result: Observable<any>;
list() {

  if (this.result === undefined) {
    this.result = this.http.get(`https://swapi.co/api/people`)
      .catch(error => {
        console.error("Something really bad happened", error);
        return Observable.of(undefined);
        // in that case, reset publishReplay
      })
      .publishReplay(1)
      .refCount();
  }

  return this.result;
}

我有一个stackblitz(使用shareReplay,但同样的问题)来显示行为:https://stackblitz.com/edit/angular-s5zuqa。 单击“加载”应该重新请求http源,而不是从catch中提供缓存的对象。

2 个答案:

答案 0 :(得分:3)

所以,如果我理解正确,你就是在寻找这个,对吧?这里有两件重要的事情需要注意:

  1. 我们使用shareReplay(1)代替publishReplay(1).refCount()
  2. catch已移至后面的多播运营商。
  3. 你第一次看到(伪造的)HTTP调用错误,发出undefined(因为我们抓住它)。下一次,我们再次运行请求,这次获得第三次运行缓存的结果(42),不会导致另一个请求。

    &#13;
    &#13;
    // Just to keep track of how often we sent the request already
    let counter = 1;
    
    // A fake HTTP request which errors the first time, then succeeds
    const request$ = Rx.Observable.of(null)
      .do(() => console.log('HTTP Request (#' + counter + ')!'))
      .delay(250)
      .switchMap(() => counter++ === 1 
        ? Rx.Observable.throw('Error!')
        : Rx.Observable.of(42)
      );
    
    // =========
    
    const result$ = request$
      .shareReplay(1)
      .catch(() => Rx.Observable.of(undefined))
    ;
    
    Rx.Observable.timer(0, 1000)
      .take(3)
      .do(() => console.log('Subscribing to result$…'))
      .switchMap(() => result$)
      .subscribe(value => console.log('Received value: ', value));
    &#13;
    <script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.min.js"></script>
    &#13;
    &#13;
    &#13;

答案 1 :(得分:0)

请谨慎使用 TIMESTAMP_FORMAT('2017-03-01 14:26:02.646171', 'YYYY-MM-DD HH24:MI:SS.NNNNNN') 。取消订阅和引用计数会带来一些麻烦。

新的配置参数已添加到shareReplay(1)中,以解决此问题。

此问题在这里得到了更好的解释:

https://github.com/ReactiveX/rxjs/issues/3336

到目前为止,新功能即将推出,但尚未发布。

https://github.com/ReactiveX/rxjs/pull/4059