Diferença entre o Flatmap e o Switchmap no RxJava
1. Visão geral
O RxJava fornece vários operadores para transformar itens emitidos por um observável em outros observáveis. Dois dos operadores mais populares sãoflatMap eswitchMap. A diferença entre os dois é muitas vezes difícil de entender para iniciantes em programação reativa.
Para obter uma introdução ao RxJava, consultethis article.
Neste tutorial, vamos entender a diferença percorrendo um exemplo simples.
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. A ordem em que os observáveis são mesclados não tem garantia de ser a mesma que na fonteObservable.
Vejamos um mecanismo de pesquisa como exemplo. Considere que queremos exibir os resultados da pesquisa imediatamente após digitar cada caractere da palavra:
Para simplificar, consideramos a entrada da consulta de pesquisa como uma lista de palavras.
Além disso, sempre retornamos dois resultados de pesquisa para cada palavra.
// 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"));
Observe que a ordem nem sempre é a mesma em todas as execuções.
3. switchMap
O operadorswitchMap é semelhante aflatMap, exceto que retém o resultado apenas do último observável, descartando os anteriores.
Vamos mudar nosso requisito, pois queremos obter resultados de pesquisa apenas para a palavra final totalmente formada (neste caso, "livros") e não para as strings de consulta parciais. Para conseguir isso, podemos usarswitchMap.
Se apenas substituirmosflatMap porswitchMap no exemplo de código acima, as seguintes afirmações seriam válidas:
assertEquals(2, actualOutput.size());
assertThat(actualOutput, hasItems("books FirstResult", "books SecondResult"));
Como vemos aqui, só temos um único observável contendo o item de entrada mais recente da fonte observável. Todos os resultados anteriores foram descartados.
4. Conclusão
Para resumir,switchMap difere deflatMap porque retém apenas a saída da aplicação de uma função fornecida ao último item emitido pela fonte Observável,flatMap, por outro lado, retém todos resultados e os retorna de forma intercalada sem garantir a ordem.
Como sempre, o código usado neste artigo está disponívelover on GitHub.