2017-12-28 27 views
0

私は、httpリクエストをAngular5でキャッシュするために、publishReplay(1).refCount()を使用しています。これは正常に動作します - エラーの場合を除きます。rxjs publishReplay:リセット時にリセット

私は飲み込んで、http-sourceから例外を報告しています。そのため、以下のコードでObservable.of(undefined)を渡しています。その場合、キャッシュは未定義ですが、サブスクライバはその値を取得すべきではありません。代わりに、キャッシュが存在しないようにhttpリソースに対して再度要求する必要があります。

私の現在のコード:https://stackblitz.com/edit/angular-s5zuqa

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; 
} 

私は挙動を示すために(shareReplayと、同じ問題)stackblitzを持っています。 「ロード」をクリックすると、キャッチからキャッシュされたオブジェクトを提供するのではなく、http-sourceを再要求する必要があります。

+0

»それはまたpublishReplay'は、それらのホールドを取得する '前に、エラー応答はあなたがすべてのエラーをキャッチし、離れてマッピングされている«キャッシュします。それが実現するどんな誤りの振る舞いでも、そのソースには観察可能なエラーが存在しないので、決して重要ではありません。 –

+0

»次回は«次回は*とは何ですか?次の定期購入ですか?これを参照するべきかどうか?私の意見では、質問は不明です。 –

+0

あなたは正しいです。私は私の質問を明確にしようとし、スタックブリッツを提供した。あなたが推測したように、私は以前にエラーが発生した場合、httpリソースを再要求するようにサブスクライバに依頼します。 – Daniel

答えて

2

私が正しく理解すれば、あなたはこれを探していますよね?

  1. 我々はshareReplay(1)代わりのpublishReplay(1).refCount()を使用します。ここで注意すべき重要なことが2つあります。
  2. catchは、マルチキャストオペレータの後ろのに移動されました。

undefined(私たちはそれを捕まえるので)を送信すると、(偽装された)HTTP呼び出しエラーが最初に表示されます。次回は、リクエストを再度実行します。今回は、3回目の実行でキャッシュされた結果(42)が取得され、別のリクエストは発生しません。

// 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));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.min.js"></script>

+0

それだけです!ありがとう – Daniel

関連する問題