La définition rxjava doc de switchmap est assez vague et renvoie à la même page que flatmap. Quelle est la différence entre les deux opérateurs?
La définition rxjava doc de switchmap est assez vague et renvoie à la même page que flatmap. Quelle est la différence entre les deux opérateurs?
Réponses:
D'après la documentation ( http://reactivex.io/documentation/operators/flatmap.html )
le switchMap
est comme le flatMap
, mais il n'émettra que des éléments de la nouvelle observable jusqu'à ce qu'un nouvel événement soit émis par l'observable source.
Le diagramme en marbre le montre bien. Notez la différence dans les diagrammes:
Dans switchMap
la deuxième émission d' origine ( marbre vert ) n'émet pas sa deuxième émission cartographiée ( carré vert ), puisque la troisième émission d' origine ( marbre bleu ) a commencé et a déjà émis sa première émission cartographiée ( diamant bleu ). En d'autres termes, seule la première des deux émissions vertes cartographiées se produit; aucun carré vert n'est émis car le diamant bleu l'a battu.
Dans flatMap
, tous les résultats mappés seront émis, même s'ils sont "périmés". En d'autres termes, le premier et le deuxième des émissions vertes cartographiées se produisent - un carré vert aurait été émis (s'ils utilisaient une fonction de carte cohérente; puisqu'ils ne l'ont pas fait, vous voyez le deuxième diamant vert, même s'il est émis après le premier diamant bleu)
flatMap
.map(func).switch
, mais c'est la même chose que .switchMap(func)
.
Je suis tombé sur cela lors de la mise en œuvre de la "recherche instantanée" - c'est-à-dire lorsque l'utilisateur tape dans une zone de texte et que les résultats apparaissent presque en temps réel à chaque coup de touche. La solution semble être:
Avec flatMap, les résultats de la recherche peuvent être obsolètes, car les réponses de recherche peuvent revenir dans le désordre. Pour résoudre ce problème, switchMap doit être utilisé, car il garantit qu'une ancienne observable est désabonnée une fois qu'une plus récente est fournie.
Donc, en résumé, flatMap doit être utilisé lorsque tous les résultats comptent, quel que soit leur timing, et switchMap doit être utilisé lorsque seuls les résultats de la dernière matière observable.
Aucune discussion flatMap n'est complète sans comparaison et contraste avec switchMap
, concatMap
et concatMapEager
.
Toutes ces méthodes prennent un Func1
qui transforme le flux en Observable
s qui sont ensuite émis; la différence est lorsque les Observable
s retournés sont souscrits et désabonnés, et si et quand ceux-ci les émissions de ces Observable
s sont émises par l' ____Map
opérateur en question.
flatMap
souscrit à autant d'émissions Observable
que possible. (C'est un numéro dépendant de la plate-forme. Par exemple, un nombre inférieur sur Android) Utilisez-le lorsque la commande n'est PAS importante et que vous voulez des émissions dès que possible.concatMap
souscrit au premier Observable
et ne souscrit au suivant que Observable
lorsque le précédent est terminé. Utilisez-le lorsque l'ordre est important et que vous souhaitez conserver les ressources. Un exemple parfait est de reporter un appel réseau en vérifiant d'abord le cache. Cela peut généralement être suivi d'un .first()
ou .takeFirst()
pour éviter de faire un travail inutile.
http://blog.danlew.net/2015/06/22/loading-data-from-multiple-sources-with-rxjava/
concatMapEager
fonctionne à peu près de la même manière mais s'abonne à autant que possible (dépend de la plate-forme) mais n'émettra qu'une fois le précédent Observable
terminé. Parfait lorsque vous avez beaucoup de traitement parallèle à faire, mais (contrairement à flatMap) vous souhaitez conserver l'ordre d'origine.
switchMap
s'abonnera aux dernières Observable
rencontres et se désabonnera de tous les précédents Observable
. C'est parfait pour des cas tels que les suggestions de recherche: une fois qu'un utilisateur a changé sa requête de recherche, l'ancienne requête n'a plus aucun intérêt, elle est donc désabonnée et un point de terminaison Api bien comporté annulera la requête réseau.Si vous retournez des Observable
s qui ne font pas partie d' subscribeOn
un autre thread, toutes les méthodes ci-dessus peuvent se comporter sensiblement de la même manière. Le comportement intéressant et utile apparaît lorsque vous autorisez les Observable
s imbriqués à agir sur leurs propres threads. Ensuite, vous pouvez obtenir de nombreux avantages du traitement parallèle et en vous désabonnant ou en ne vous abonnant pas intelligemment des Observable
s qui n'intéressent pas vos Subscriber
s
amb
peut également présenter un intérêt. Étant donné un nombre quelconque de Observable
s, il émet les mêmes éléments que le premier Observable
à émettre quoi que ce soit. Cela peut être utile lorsque vous avez plusieurs sources qui pourraient / devraient renvoyer la même chose et que vous voulez des performances. Par exemple, le tri, vous pouvez effectuer amb
un tri rapide avec un tri par fusion et utiliser celui qui est le plus rapide.If you are returning Observables that don't subscribeOn another thread, all of the above methods may behave much the same.
- chaque explication que switchMap vs flatMap
j'ai rencontrée auparavant, j'ai raté cet aspect important, maintenant tout est plus clair. Je vous remercie.
switchMap s'appelait autrefois flatMapLatest dans RxJS 4.
Il transmet simplement les événements du dernier Observable et se désabonne du précédent.
Map, FlatMap, ConcatMap et SwitchMap applique une fonction ou modifie les données émises par un observable.
Map modifie chaque élément émis par une source Observable et émet l'élément modifié.
FlatMap, SwitchMap et ConcatMap appliquent également une fonction sur chaque élément émis mais au lieu de renvoyer l'élément modifié, il renvoie l'Observable lui-même qui peut à nouveau émettre des données.
Le travail de FlatMap et de ConcatMap est à peu près le même. Ils fusionnent les éléments émis par plusieurs observables et retournent un seul observable.
Si vous recherchez un exemple de code
/**
* 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);
}
Vous pouvez voir plus d'exemples ici https://github.com/politrons/reactive
switchMap
par, flatMap
cela fonctionnera exactement de la même manière.
Voici une plus - 101 longue ligne par exemple . Cela explique la chose pour moi.
Comme on l'a dit: il obtient le dernier observable (le plus lent si vous voulez) et ignore le reste.
Par conséquent:
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
Vous voyez que le A a été ignoré.