La définition de rxjava doc de switchmap est plutôt vague et renvoie au même page sous forme de flatmap. Quelle est la différence entre les deux opérateurs?
Selon la documentation ( http://reactivex.io/documentation/operators/flatmap.html )
la switchMap
est semblable à la flatMap
, mais elle émettra uniquement les éléments du nouvel observable jusqu'à ce qu'un nouvel événement soit émis à partir de la source observable.
Le diagramme en marbre le montre bien ... Notez la différence entre les diagrammes:
Dans switchMap
, la deuxième originale émission (marbre vert) n'émet pas sa deuxième cartographiée émission (carré vert), puisque la troisième original émission (marbre bleu) a commencé et a déjà émis sa première émission mappée (diamant bleu). En d’autres termes, seul le premier de deux cartographiées émissions vertes se produit; aucun carré vert n'est émis car le diamant bleu le bat.
Dans flatMap
, tous les résultats cartographiés seront émis, même s'ils sont "périmés". En d'autres termes, les deux premiers et deuxièmes des cartographiées émissions vertes se produisent - un carré vert aurait été émis (s'ils avaient utilisé fonction de carte cohérente; comme 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
Je suis tombé sur cette information lors de la mise en oeuvre de la "recherche instantanée", c’est-à-dire lorsque l’utilisateur tapait dans une zone de texte et que les résultats apparaissaient presque en temps réel à chaque frappe. La solution semble être:
Avec flatMap, les résultats de la recherche peuvent être obsolètes, car les réponses à la recherche risquent de ne plus être correctes. Pour résoudre ce problème, switchMap doit être utilisé, car il garantit qu’un ancien observable est désabonné une fois qu'un nouvel observateur est fourni.
Donc, en résumé, flatMap doit être utilisé lorsque tous les résultats importent, quel que soit le moment choisi, et switchMap doit être utilisé uniquement lorsque les résultats proviennent de la dernière matière Observable.
Aucune discussion à plat n'est complète sans comparer et contraster avec switchMap
, concatMap
et concatMapEager
.
Toutes ces méthodes prennent un Func1
qui transforme le flux en Observable
s qui sont ensuite émises; la différence correspond au moment où les Observable
s retournés sont abonnés et désabonnés, et si et quand, les émissions de ces Observable
s sont émises par l'opérateur ____Map
en question.
flatMap
souscrit à autant de Observable
s émis que possible. (Il s’agit d’un numéro dépendant de la plate-forme. Par exemple, un nombre inférieur sur Android). Utilisez cette option lorsque l’ordre n’est PAS important et que vous souhaitez des émissions dès que possible.concatMap
s'abonne à la première Observable
et ne s'abonne qu'à la suivante Observable
lorsque celle-ci est terminée. Utilisez cette option lorsque l'ordre est important et que vous souhaitez conserver les ressources. Un exemple parfait est le report d'un appel réseau en vérifiant d'abord le cache. Cela peut généralement être suivi d'une .first()
ou d'une .takeFirst()
afin d'é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 façon mais s’abonne au plus grand nombre (en fonction de la plate-forme) mais n’émet que lorsque le précédent Observable
est terminé. Parfait lorsque vous devez effectuer beaucoup de traitements en parallèle, mais (contrairement à flatMap), vous souhaitez conserver la commande d'origine.
switchMap
souscrira au dernier Observable
rencontré et se désabonnera de tous les Observable
s précédents. Ceci est parfait pour les cas tels que les suggestions de recherche: une fois qu'un utilisateur a modifié sa requête de recherche, l'ancienne requête n'a plus aucun intérêt, elle est donc désabonnée et un noeud final Api bien tenu annule la requête réseau.Si vous renvoyez Observable
s sans subscribeOn
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. Vous pouvez alors tirer de nombreux avantages du traitement en parallèle et vous désabonner ou ne pas souscrire intelligemment auprès de Observable
s qui n'intéressent pas votre Subscriber
s
amb
peut également présenter un intérêt. Quel que soit le nombre de Observable
s, il émet les mêmes éléments que le premier Observable
pour é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. amb
peut être un tri rapide avec un tri par fusion et utiliser celui qui est le plus rapide.switchMaps'appelait autrefoisflatMapLatest dans RxJS 4.
En gros, il ne fait que transmettre les événements du latest Observable et se désabonner du précédent.
Voici celui de plus - 101 lignes - exemple . Cela explique la chose pour moi.
Comme cela a été dit: il obtient la dernière observation (la plus lente 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é.
Si vous cherchez 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