2017-11-06 12 views
0

2つのデータストリームがあり、2つ目は最初のものに依存しますが、2番目のストリームの変更をキャッチできます。私はオブザーバブルを作成するための2つの関数を書いた。この実装が正しいかどうか疑問に思っています。私はswitchMap、flatMapまたはその他のrxjs演算子をAngularで使うべきでしょうか?

firstObservable(){ 
    ... 
}; 
secondObservable(someValue){ 
    ... 
} 
let subscription = firstObservable().switchMap(r => { 
    if (r.someValue){ 
    return secondObservable(r.someValue); 
    }else{ 
    return Observable.empty(); 
    } 
}).subscribe(...); 
+0

が鳴ります。それらの大きな違いは、最初の(ソース)が出るたびに、switchMapは2番目の観測可能(内部観測可能)を完了することです。 FlatMapは、最初の(ソース)が放出されたまま放つので、古い第2観測値(内部観測値)を完成させません。 – bygrace

+0

Observableが同じ型を持たないため、実装がうまくいかないかどうかわかりません。flatMapを使用していないのは、他のソースからObservableを使用していて、someValueが未定義のときにエラーが発生するためです。観察可能な第1および第2として。 –

+2

それ以外の「良い」とはどういう意味ですか?あなたが何をしようとしているのかは不明です。それは正しいアプローチのようです。 'r.someValue'が偽であるときにストリームを送出しないようにしたいのであれば、次のようにswitchmapの前でフィルタリングするだけです:' firstObservable()。filter(r => r.someValue).switchMap (r => secondObservable(r.someValue)); '。 – bygrace

答えて

0

あなたが何を求めているかについて具体的に分かっていれば、それは助けになると思いますが、私が理解しているところからはうまく見えます。

おそらく、flatMapの代わりにswitchMapを使いたいと思っています。 FlatMapは複数の内部サブスクリプションを維持しますが、SwitchMapは最新の内部オブザーバブルへのサブスクリプションのみを維持します。したがって、ソースの出力に基づいて内側のオブザーバブルからのみ値を取得したい場合は、switchMapがそれを行います。

あなたの使用例は不明ですが、Observable.empty()を返す代わりにフィルタを適用することを検討してください。ここで

は一例です:あなたはむしろflatMapよりswitchMapたいと思うように

const firstObservable = Rx.Observable.create((o) => { 
 
    o.next(); 
 
    setTimeout(() => o.next(1), 1000); 
 
    setTimeout(() => o.next(), 2000); 
 
    setTimeout(() => o.next(2), 3000); 
 
    setTimeout(() => o.complete(), 4000); 
 
}).do(console.log.bind(null, 'first: next'), 
 
    console.log.bind(null, 'first: error'), 
 
    console.log.bind(null, 'first: complete')); 
 
const secondObservable = (x) => Rx.Observable.interval(x * 500).take(5) 
 
    .do(console.log.bind(null, 'second: next'), 
 
    console.log.bind(null, 'second: error'), 
 
    console.log.bind(null, 'second: complete')); 
 

 
firstObservable.filter(x => x).switchMap(x => secondObservable(x)) 
 
    .subscribe(console.log.bind(null, 'stream: next'), 
 
    console.log.bind(null, 'stream: error'), 
 
    console.log.bind(null, 'stream: complete'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.2/Rx.js"></script>

+0

実際には、switchMapは切り替え時に内部観察可能な状態に完了しません(完全なイベントを送信しません)。完全なイベント(たとえば、配列)に依存する演算子を内部で使用した場合、それはトリガーされません。あなたの例では、completeイベントは 'switchMap'からではなく' .take(5) 'から来ています。 –

+0

switchMapはスイッチインナーが同じソースから、しかし異なる演算子から派生したケースを扱うために、このように設計されていると推測します。 switchMapが最初のスイッチでこのソースを完了すると、2番目の内部はもはや放出されません。 –

+0

@リチャードマツェン良い点。私はその完成に比べて効果に焦点を当てていました。私は答えを更新しました。 – bygrace

関連する問題