Quelle est la différence entre concatMap et flatMap en RxJava?
il semble que ces deux fonctions sont assez similaires. Ils ont la même signature (accepter rx.functions.Func1<? super T, ? extends Observable<? extends R>> func
), et leurs diagrammes de marbre sont exactement les mêmes. Je ne peux pas coller les photos ici, mais en voici une pour concatMap , et une pour flatMap . Il semble y avoir une différence subtile dans la description du Observable
qui en résulte , où le concatMap
contient des articles qui résultent de la concaténation de produits Observables, et celui produit par flatMap
contient des éléments qui résultent de la première fusion des Observables résultants, et d'émettre le résultat de cette fusion.
cependant, cette subtilité m'est totalement inconnue. Est-ce que quelqu'un peut donner une meilleure explication de cette différence, et idéalement donner quelques exemples illustrant cette différence.
3 réponses
Comme vous l'avez écrit, les deux fonctions sont très similaires et la différence subtile est la façon dont la sortie est créée ( après l'application de la fonction de mappage).
Plat carte utilise fusion "d'opérateur de 151960920" alors que concatMap utilise concat "d'opérateur de 151960920" .
comme vous voyez la séquence de sortie concatMap est ordonnée - tous les éléments émis par le premier Observable étant émis avant l'un des articles émis par le deuxième Observable,
alors que la séquence de sortie flatMap est fusionnée - les éléments émis par L'Observable fusionné peuvent apparaître dans n'importe quel ordre, quelle que soit la source Observable d'où ils proviennent.
une différence très importante: le concatMap
attend le courant émis observable à compléter et le flatMap
ne le fait pas. flatMap
essaie de démarrer le plus possible. Simplement dit - vous ne pouvez pas concaténer quelque chose d'infini. assurez-vous juste que les observables que vous émettez dans concatMap
peuvent compléter , sinon tout le flux sera coincé en attendant le courant observable à compléter pour concaténer le prochain.
même si les réponses ici sont bonnes, il n'a pas été facile de faire la différence sans un exemple. Ainsi, j'ai créé un exemple simple pour ceci:
@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);
}
******** à l'Aide de flatMap() *********
1 2 3 4 5 6 7 9 8 11 13 15 10 12 14
******** à l'Aide de concatMap() *********
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
comme il on peut voir à partir de la sortie, les résultats pour flatMap
ne sont pas classés tandis que pour concatMap
ils sont.