Il semble que ces 2 fonctions soient assez similaires. Ils ont la même signature (acceptant rx.functions.Func1<? super T, ? extends Observable<? extends R>> func
), et leurs diagrammes en marbre sont identiques. Impossible de coller les photos ici, mais en voici une pour concatMap , et en voici une pour flatMap . Il semble y avoir une différence subtile dans la description de Observable
résultant, où celui produit par concatMap
contient des éléments résultant de la concaténation des observables résultants, et celui produit par flatMap
contient les éléments qui résultent de la fusion des Observables résultants et de l'émission du résultat de cette fusion.
Cependant, cette subtilité n'est pas du tout claire pour moi. Quelqu'un peut-il donner une meilleure explication de cette différence, et idéalement donner quelques exemples illustrant cette différence.
Comme vous l'avez écrit, les deux fonctions sont très similaires et la différence subtile réside dans la façon dont la sortie est créée (après l'application de la fonction de mappage).
La carte plate utilise opérateur de fusion tandis que concatMap utilise opérateur de concat .
Comme vous le 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 éléments émis par le deuxième observable,
pendant la fusion de la séquence de sortie flatMap - les éléments émis par l'Observable fusionné peuvent apparaître dans n'importe quel ordre, quelle que soit la source d'Observable dont ils sont issus.
Une différence très importante: le concatMap
attend la fin du courant observé émis et flatMap
ne le fait pas. flatMap
essaie de démarrer autant que possible. Dit simplement - vous ne pouvez pas enchaîner quelque chose d'infini. Assurez-vous simplement que les observables que vous émettez dans concatMap
peuvent se terminer, sinon le flux entier restera bloqué en attendant que l'observable actuel se termine pour concaténer le suivant.
Même si les réponses ici sont bonnes, il n'a pas été facile de distinguer la différence sans un exemple. J'ai donc créé un exemple simple pour cela:
@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);
}
******** Utilisation de flatMap () *********
1 2 3 4 5 6 7 9 8 11 13 15 10 12 14
******** Utilisation de concatMap () *********
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Comme on peut le voir sur la sortie, les résultats pour flatMap
ne sont pas ordonnés tandis que pour concatMap
ils le sont.