web-dev-qa-db-ja.com

RxJavaのflatmapとswitchmapの違いは何ですか?

rxjava doc switchmapの定義はかなりあいまいで、 同じページ にflatmapとしてリンクしています。 2つの演算子の違いは何ですか?

134
Julian Go

ドキュメントによると( http://reactivex.io/documentation/operators/flatmap.html

switchMapflatMapに似ていますが、butソースobservableから新しいイベントが発行されるまで、新しいobservableからのみアイテムを発行します。

大理石の図はそれをよく示しています。図の違いに注意してください。

switchMapでは、2番目のoriginalエミッション(green marble)は2番目のmappedエミッション(緑の四角)、3番目のoriginalの放出(blue marble)が開始され、その最初のmappedエミッション(ブルーダイヤモンド)。言い換えると、2つのmappedグリーンエミッションのうち、firstのみが発生します。青いダイアモンドがそれを打ち負かしたので、緑色の正方形は放出されません。

flatMapでは、マップされた結果が「古い」場合でもすべて出力されます。つまり、bothfirstandsecond of themappedgreen放出が発生します-緑の正方形が放出されます(一貫したマップ機能を使用した場合;使用しなかったため、second緑が表示されますダイヤモンド、afterthefirstblue diamond)

switchMapin switchMap if the original observable emits something new, previous emissions no longer produce mapped observables; this is an effective way to avoid stale results

flatMap

in switchMap if the original observable emits something new, previous emissions no longer produce mapped observables; this is an effective way to avoi stale results

162
dwursteisen

「インスタント検索」を実装するときに、つまり、ユーザーがテキストボックスに入力すると、キーストロークごとにほぼリアルタイムで結果が表示されます。解決策は次のようです:

  1. 文字列のPublishSubjectなどの件名があります
  2. テキストボックス変更コールバックで、.onNext(text)を呼び出します
  3. .debounceフィルターを適用して、サーバークエリのレート制限を行う
  4. .switchMapを適用してサーバークエリを実行します-検索語を取得し、ObservableのSearchResponseを返します
  5. searchResponseを使用してUIを更新するメソッドで.subscribeを適用します。

FlatMapを使用すると、検索応答が順不同になる可能性があるため、検索結果が古くなる可能性があります。これを修正するには、switchMapを使用する必要があります。新しいオブザーバブルが提供されると、古いオブザーバブルがサブスクライブされないようにするためです。

したがって、要約すると、タイミングに関係なくすべての結果が重要な場合はflatMapを使用し、最後のObservableの結果のみが結果の場合はswitchMapを使用する必要があります。

161
user4698855

switchMap一度呼び出されたRxJSのflatMapLatest 4。

基本的には、latestObservableからのイベントを渡し、前のイベントからサブスクライブを解除します。

53
Sentenza

もう1つ-101行の長さ です。それは私のために物事を説明しています。

言われたように:最後の観測可能なもの(あなたがそうするなら最も遅いもの)を取得し、残りを無視します。

結果として:

Time | scheduler | state
----------------------------
0    | main      | Starting
84   | main      | Created
103  | main      | Subscribed
118  | Sched-C-0 | Going to emmit: A
119  | Sched-C-1 | Going to emmit: B
119  | Sched-C-0 | Sleep for 1 seconds for A
119  | Sched-C-1 | Sleep for 2 seconds for B
1123 | Sched-C-0 | Emitted (A) in 1000 milliseconds
2122 | Sched-C-1 | Emitted (B) in 2000 milliseconds
2128 | Sched-C-1 | Got B processed
2128 | Sched-C-1 | Completed

Aが無視されたことがわかります。

1
ses

サンプルコードを探している場合

/**
 * We switch from original item to a new observable just using switchMap.
 * It´s a way to replace the Observable instead just the item as map does
 * Emitted:Person{name='Pablo', age=0, sex='no_sex'}
 */
@Test
public void testSwitchMap() {
    Observable.just(new Person("Pablo", 34, "male"))
              .switchMap(person -> Observable.just(new Person("Pablo", 0, "no_sex")))
              .subscribe(System.out::println);

}

ここでより多くの例を見ることができます https://github.com/politrons/reactive

1
paul