A definição de switchmap para rxjava doc é bastante vaga e está vinculada à mesma página que o flatmap. Qual é a diferença entre os dois operadores?
A definição de switchmap para rxjava doc é bastante vaga e está vinculada à mesma página que o flatmap. Qual é a diferença entre os dois operadores?
Respostas:
De acordo com a documentação ( http://reactivex.io/documentation/operators/flatmap.html )
o switchMap
é como o flatMap
, mas só emitirá itens do novo observável até que um novo evento seja emitido a partir da fonte observável.
O diagrama de mármore mostra bem. Observe a diferença nos diagramas:
Na switchMap
segunda emissão original ( mármore verde ) não emite sua segunda emissão mapeada ( quadrado verde ), desde que a terceira emissão original ( mármore azul ) começou e já emitiu sua primeira emissão mapeada ( diamante azul ). Em outras palavras, apenas a primeira das duas emissões verdes mapeadas acontece; nenhum quadrado verde é emitido porque o diamante azul o venceu.
Em flatMap
, todos os resultados mapeados serão emitidos, mesmo que sejam "obsoletos". Em outras palavras, a primeira e a segunda das emissões verdes mapeadas acontecem - um quadrado verde seria emitido (se usassem a função de mapa consistente; como não o fizeram, você verá o segundo diamante verde, mesmo que seja emitido após o primeiro diamante azul)
flatMap
.map(func).switch
, mas é o mesmo que .switchMap(func)
.
Me deparei com isso ao implementar a "pesquisa instantânea" - ou seja, quando o usuário digita em uma caixa de texto e os resultados aparecem quase em tempo real a cada toque de tecla. A solução parece ser:
Com o flatMap, os resultados da pesquisa podem ficar obsoletos, pois as respostas da pesquisa podem ficar fora de ordem. Para corrigir isso, o switchMap deve ser usado, pois garante que um observável antigo seja cancelado quando um novo for fornecido.
Portanto, em resumo, o flatMap deve ser usado quando todos os resultados importam, independentemente de seu tempo, e o switchMap deve ser usado quando apenas resultados do último assunto observável.
Nenhuma discussão flatMap é concluída sem comparar e contrastar com switchMap
, concatMap
e concatMapEager
.
Todos esses métodos usam um Func1
que transforma o fluxo em Observable
s que são então emitidos; a diferença é quando os Observable
s retornados são inscritos e não inscritos e se e quando esses as emissões desses Observable
s são emitidas pelo ____Map
operador em questão.
flatMap
assina o maior número Observable
possível de s emitidos . (É um número dependente da plataforma. Por exemplo, um número mais baixo no Android) Use-o quando a ordem NÃO for importante e você desejar emissões o mais rápido possível.concatMap
assina o primeiro Observable
e só assina o próximo Observable
quando o anterior for concluído. Use isso quando a ordem for importante e você desejar economizar recursos. Um exemplo perfeito é adiar uma chamada de rede verificando primeiro o cache. Isso geralmente pode ser seguido por um .first()
ou .takeFirst()
para evitar um trabalho desnecessário.
http://blog.danlew.net/2015/06/22/loading-data-from-multiple-sources-with-rxjava/
concatMapEager
funciona da mesma forma, mas assina o maior número possível (dependendo da plataforma), mas só será emitido quando o anterior Observable
for concluído. Perfeito quando você tem muito processamento paralelo que precisa ser feito, mas (ao contrário do flatMap) deseja manter a ordem original.
switchMap
assinará o último Observable
que encontrar e cancelará a assinatura de todos os Observable
s anteriores . Isso é perfeito para casos como sugestões de pesquisa: depois que um usuário altera sua consulta de pesquisa, a solicitação antiga não tem mais interesse e, portanto, é cancelada a inscrição, e um ponto de extremidade da API bem comportado cancelará a solicitação de rede.Se você está retornando Observable
s que não possuem subscribeOn
outro encadeamento, todos os métodos acima podem se comportar da mesma forma. O comportamento interessante e útil surge quando você permite que os Observable
s aninhados atuem em seus próprios encadeamentos. Em seguida, você poderá obter muitos benefícios do processamento paralelo e cancelar de maneira inteligente a inscrição ou não a inscrição de Observable
s que não interessam aos seus Subscriber
s
amb
também pode ser interessante. Dado qualquer número de Observable
s, emite os mesmos itens que o primeiro Observable
a emitir qualquer coisa. Isso pode ser útil quando você tem várias fontes que podem / devem retornar a mesma coisa e desejam desempenho. por exemplo, classificação, você pode fazer amb
uma classificação rápida com uma classificação de mesclagem e usar o que for mais rápido.If you are returning Observables that don't subscribeOn another thread, all of the above methods may behave much the same.
- todas as explicações switchMap vs flatMap
que encontrei antes, perderam esse aspecto importante, agora tudo está mais claro. Obrigado.
O switchMap já foi chamado flatMapLatest no RxJS 4.
Basicamente, apenas transmite os eventos do Observable mais recente e cancela a inscrição do anterior.
Map, FlatMap, ConcatMap e SwitchMap aplicam uma função ou modificam os dados emitidos por um Observable.
O mapa modifica cada item emitido por uma fonte observável e emite o item modificado.
O FlatMap, SwitchMap e ConcatMap também aplicam uma função em cada item emitido, mas, em vez de retornar o item modificado, ele retorna o próprio Observable, que pode emitir dados novamente.
O trabalho do FlatMap e ConcatMap é praticamente o mesmo. Eles mesclam itens emitidos por vários observáveis e retornam um único observável.
Se você está procurando um código de exemplo
/**
* We switch from original item to a new observable just using switchMap.
* It´s a way to replace the Observable instead just the item as map does
* Emitted:Person{name='Pablo', age=0, sex='no_sex'}
*/
@Test
public void testSwitchMap() {
Observable.just(new Person("Pablo", 34, "male"))
.switchMap(person -> Observable.just(new Person("Pablo", 0, "no_sex")))
.subscribe(System.out::println);
}
Você pode ver mais exemplos aqui https://github.com/politrons/reactive
switchMap
por flatMap
ele funcionará exatamente da mesma forma.
Aqui está a mais uma - 101 longa linha exemplo . Isso explica a coisa para mim.
Como foi dito: ele obtém o último observável (o mais lento, se você preferir) e ignora o resto.
Como um resultado:
Time | scheduler | state
----------------------------
0 | main | Starting
84 | main | Created
103 | main | Subscribed
118 | Sched-C-0 | Going to emmit: A
119 | Sched-C-1 | Going to emmit: B
119 | Sched-C-0 | Sleep for 1 seconds for A
119 | Sched-C-1 | Sleep for 2 seconds for B
1123 | Sched-C-0 | Emitted (A) in 1000 milliseconds
2122 | Sched-C-1 | Emitted (B) in 2000 milliseconds
2128 | Sched-C-1 | Got B processed
2128 | Sched-C-1 | Completed
Você vê o A ignorado.