これらの2つの関数はかなり似ているようです。署名は同じです(rx.functions.Func1<? super T, ? extends Observable<? extends R>> func
)、およびそれらの大理石図はまったく同じに見えます。ここに写真を貼り付けることはできませんが、これは concatMap の場合と flatMap の場合です。結果のObservable
の記述には微妙な違いがあるようです。concatMap
によって生成されたものには、結果のObservableを連結した結果のアイテムが含まれ、flatMap
によって生成されたものには、結果のObservablesを最初にマージし、その合併。
しかし、この微妙さは私にはまったくわかりません。誰でもこの違いのより良い説明を与えることができ、理想的にはこの違いを示すいくつかの例を与えることができます。
あなたが書いたように、2つの関数は非常に似ており、微妙な違いは出力の作成方法です(マッピング関数が適用された後)。
フラットマップでは マージ演算子 を使用しますが、concatMapでは concat演算子 を使用します。
ConcatMapの出力シーケンスが順序付けられているのを確認します。最初のObservableによって発行されたすべてのアイテムは、2番目のObservableによって発行されたアイテムよりも前に発行されます。
flatMapの出力シーケンスがマージされている間-マージされたObservableによって発行されたアイテムは、どのソースObservableに由来するかに関係なく、任意の順序で表示されます。
1つの非常に重要な違い:concatMap
は、現在の発行されたobservableが完了するまで待機し、flatMap
は完了しません。 flatMap
はできるだけ多くの起動を試みます。簡単に言うと、無限のものを連結することはできません。 concatMap
で出力するオブザーバブルが完了できることを確認してください.
ここでの答えは良いものの、例がなければ違いを見つけるのは簡単ではありませんでした。そこで、このための簡単な例を作成しました。
@Test
public void flatMapVsConcatMap() throws Exception {
System.out.println("******** Using flatMap() *********");
Observable.range(1, 15)
.flatMap(item -> Observable.just(item).delay(1, TimeUnit.MILLISECONDS))
.subscribe(x -> System.out.print(x + " "));
Thread.sleep(100);
System.out.println("\n******** Using concatMap() *********");
Observable.range(1, 15)
.concatMap(item -> Observable.just(item).delay(1, TimeUnit.MILLISECONDS))
.subscribe(x -> System.out.print(x + " "));
Thread.sleep(100);
}
******** flatMap()を使用***********
1 2 3 4 5 6 7 9 8 11 13 15 10 12 14
******** concatMap()の使用***********
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
出力からわかるように、flatMap
の結果は順不同ですが、concatMap
の結果は順不同です。