Différence entre Flatmap et Switchmap dans RxJava

Différence entre Flatmap et Switchmap dans RxJava

1. Vue d'ensemble

RxJava fournit différents opérateurs pour transformer les éléments émis par un observable en d'autres observables. Deux des opérateurs les plus courants sontflatMap etswitchMap. La différence entre les deux est souvent difficile à comprendre pour les débutants en programmation réactive.

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

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

2. flatMap

The flatMap operator converts each item returned from a source observable into an independent observable using the supplied function and then merges all the observables into a single observable. L'ordre dans lequel les observables sont fusionnés n'est pas garanti comme dans la sourceObservable.

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érateurswitchMap 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 souhaitons 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 utiliserswitchMap.

Si nous remplaçons simplementflatMap parswitchMap 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 reçu qu’une seule observable contenant le dernier élément d’entrée de la source observable. Tous les résultats précédents ont été écartés.

4. Conclusion

Pour résumer,switchMap diffère deflatMap 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 tout résultats et les renvoie de manière entrelacée sans garantir l'ordre.

Comme toujours, le code utilisé dans cet article est disponibleover on GitHub.