Différence entre Flatmap et Switchmap dans RxJava

1. Vue d'ensemble

RxJava fournit divers opérateurs pour transformer les éléments émis par une observable en d'autres observables. Deux des opérateurs les plus populaires sont flatMap et switchMap . La différence entre les deux est souvent difficile à comprendre pour les débutants en programmation réactive.

Pour une introduction à RxJava, reportez-vous à cet article.

Dans ce didacticiel, nous comprendrons la différence en parcourant un exemple simple.

2. flatMap

L' opérateur flatMap convertit chaque élément renvoyé par une observable source en une observable indépendante à l'aide de la fonction fournie, puis fusionne toutes les observables en une seule observable . L'ordre dans lequel les observables sont fusionnés n'est pas garanti être le même que dans la source Observable.

Prenons un moteur de recherche comme exemple. Considérez que nous voulons afficher les résultats de la recherche immédiatement après avoir tapé chaque caractère du mot:

Par souci de simplicité, nous avons pris l'entrée de la requête de recherche comme une liste de mots.

De plus, nous renvoyons toujours deux résultats de recherche pour chaque mot.

// given List actualOutput = new ArrayList(); TestScheduler scheduler = new TestScheduler(); List keywordToSearch = Arrays.asList("b", "bo", "boo", "book", "books"); // when Observable.fromIterable(keywordToSearch) .flatMap(s -> Observable.just(s + " FirstResult", s + " SecondResult") .delay(10, TimeUnit.SECONDS, scheduler)) .toList() .doOnSuccess(s -> actualOutput.addAll(s)) .subscribe(); scheduler.advanceTimeBy(1, TimeUnit.MINUTES); // then assertThat(actualOutput, hasItems("b FirstResult", "b SecondResult", "boo FirstResult", "boo SecondResult", "bo FirstResult", "bo SecondResult", "book FirstResult", "book SecondResult", "books FirstResult", "books SecondResult"));

Veuillez noter que l'ordre n'est pas toujours le même à chaque exécution.

3. switchMap

L' opérateur switchMap est similaire à flatMap , sauf qu'il ne conserve que le résultat de la dernière observable, en ignorant les précédentes.

Modifions notre exigence en ce que nous voulons obtenir des résultats de recherche uniquement pour le mot final entièrement formé (dans ce cas, «livres») et non pour les chaînes de requête partielles. Pour y parvenir, nous pouvons utiliser switchMap .

Si nous remplaçons simplement flatMap par switchMap dans l'exemple de code ci-dessus, les assertions suivantes seraient valides:

assertEquals(2, actualOutput.size()); assertThat(actualOutput, hasItems("books FirstResult", "books SecondResult"));

Comme nous le voyons ici, nous n'avons qu'une seule observable contenant le dernier élément d'entrée de l'observable source. Tous les résultats précédents ont été ignorés.

4. Conclusion

Pour résumer, switchMap diffère de flatMap en ce qu'il ne conserve que la sortie de l'application d'une fonction fournie au dernier élément émis par la source Observable, flatMap , en revanche, conserve tous les résultats et les renvoie de manière entrelacée sans garantir l'ordre.

Comme toujours, le code utilisé dans cet article est disponible à l'adresse over sur GitHub.