Diferencia entre Flatmap y Switchmap en RxJava

1. Información general

RxJava proporciona varios operadores para transformar elementos emitidos por un observable en otros observables. Dos de los operadores más populares son flatMap y switchMap . La diferencia entre los dos es a menudo difícil de entender para los principiantes en programación reactiva.

Para obtener una introducción a RxJava, consulte este artículo.

En este tutorial, entenderemos la diferencia con un ejemplo sencillo.

2. flatMap

El operador flatMap convierte cada elemento devuelto por una fuente observable en un observable independiente utilizando la función proporcionada y luego fusiona todos los observables en un solo observable . No se garantiza que el orden en el que se fusionan los observables sea el mismo que en la fuente Observable.

Tomemos un motor de búsqueda como ejemplo. Considere que queremos mostrar los resultados de la búsqueda inmediatamente después de escribir cada carácter de la palabra:

En aras de la simplicidad, hemos tomado la entrada de la consulta de búsqueda como una lista de palabras.

Además, siempre devolvemos dos resultados de búsqueda por cada palabra.

// 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"));

Tenga en cuenta que el orden no siempre es el mismo con cada ejecución.

3. switchMap

El operador switchMap es similar a flatMap , excepto que retiene el resultado solo del último observable, descartando los anteriores.

Cambiemos nuestro requisito en el sentido de que queremos obtener resultados de búsqueda solo para la palabra final completamente formada (en este caso, "libros") y no para las cadenas de consulta parciales. Para lograr esto, podemos usar switchMap .

Si simplemente reemplazamos flatMap con switchMap en el ejemplo de código anterior, las siguientes afirmaciones serían válidas:

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

Como vemos aquí, solo obtuvimos un único observable que contiene el último elemento de entrada del observable de origen. Se descartaron todos los resultados anteriores.

4. Conclusión

Para resumir, switchMap difiere de flatMap en que solo conserva el resultado de aplicar una función proporcionada al último elemento emitido por la fuente Observable, flatMap , por otro lado, conserva todos los resultados y los devuelve de manera intercalada sin garantizar el orden.

Como siempre, el código utilizado en este artículo está disponible en GitHub.