2017-03-27 23 views
2

約束事では、エラーが発生したときに.thenの亜種を使用してチェーンを分割できます。ここではこれは私が応答処理ロジックをスキップしてのみオリジナルのfetch文に提起されたエラーに応答することができますfetchRxJSでエラーが発生するとスプリットが発生する

fetch('http://website.com').then(
    // Perform some logic 
    (response) => response.json().then(({ answer }) => `Your answer: ${answer}`), 
    // Skip json parsing when an error occurs 
    (error) => 'An error occurred :(', 
).then(console.log); 

を使用した例です。 RxJSで同様の何かが次のようになります。コードの状態でのコメントは、私は単にそれが私の約束チェーンと同じ動作を持っていないようにキャッチ演算子を置くことができない

Observable.fromPromise(fetch('http://website.com')) 
    // if I put .catch here, the result will be piped into flatMap and map 
    .flatMap(response => response.json()) 
    .map(({ answer }) => `Your answer: ${answer}`) 
    // if I put .catch here, errors thrown in flatMap and map will also be caught 
    .subscribe(console.log); 

通り。

私は、マテリアライズ、またはこれと観測可能なエラーをマージするカスタム演算子でそれを得ることができると知っていますが、それはすべてかなり重大な過度のようです。約束の連鎖行動を達成する簡単な方法はありますか?

答えて

6

実際に私があなたの状況にあった場合、私はflatMapmapからエラーをキャッチすることを心配しません。 Observableソースがエラーをスローすると、オブザーバに伝播されます。呼び出すときだから、僕は(そうでない場合、エラーが再スローされる)購読するエラーハンドラを使用したい:

.subscribe(console.log, err => console.log('error:', err)); 

エラーが(あなたのケースでの約束)観察可能なソースで発生したとき、それはerror通知として伝播されますことことに注意してください標準ではありません。next通知。 これは、flatMap()map()がエラーメッセージに全く影響しないことを意味します。 catch()またはmaterialize()を使用した場合、両方の演算子(flatMapmap)はこのタイプのデータを処理できなければならず、さらに別のエラーをスローする必要はありません。

とにかくあなたは常にshare()publish()を使用し、各ハンドルの信号の一種類のみ二つの異なるサブスクリプションを作ることができます。

let source = Observable.fromPromise(fetch('http://website.com')).publish(); 

source 
    .subscribe(undefined, err => console.log(err)); 

source 
    .flatMap(...) 
    .map(...) 
    .subscribe(console.log,() => {}); 

source.connect(); 

は、今私が唯一のエラーのために別々のオブザーバを持っています。

() => {}で空のコールバックを作成しなければならないことに注意してください。エラーは暗黙のうちに無視されます。また、マルチキャスティング(publish()演算子)を使用する場合、Subject内部には注意すべき動作がいくつかあるかもしれませんが、ユースケースでは問題ではないことに注意してください。

+0

2種類のエラーを区別したいのは、合理的に回復できるか、または「フェッチ」からのエラーから何らかのフィードバックを与えることができるためです(ネットワークに何か問題があるなど)。 flatMapまたはmapでエラーが発生した場合は、自分のエラーである可能性が高いので、エラーがそのサブスクライバに伝播されるようにしたいと考えています。 – Pinpickle

+0

私はあなたの解決策が気に入っていますが、私の目標は結果(この場合はエラーからの文字列またはjsonの解析)を同じ観察可能な部分にすることです。あなたは2つをマージすることをお勧めしますか? – Pinpickle

+1

私はおそらく 'Observable.fromPromise()'の直後に 'catch()'を使って、自分のエラークラス( 'catch()')でエラーをラップしただけで、自分のエラークラスでエラーを 'error 'シグナル)。後でオブザーバーでエラーがtypeofかどうか、または特定のクラスを実装しているかどうかを確認できます。これは、エラーが 'fromPromise'で発生し、' catch() 'で捕捉されたかどうか、例えば、 'map'は通常のエラーです。たぶん、エラーをキャッチするretryWhen()演算子を見てみましょうが、あなた自身の通知に基づいて自動的に再登録しましょう... – martin

関連する問題