Ich habe viele Antworten zu RxJava gefunden, möchte aber verstehen, wie es in Reactor funktioniert.
Mein aktuelles Verständnis ist sehr vage, ich neige dazu, mir Map als synchron und flatMap als asynchron vorzustellen, aber ich komme damit nicht wirklich klar.
Ich habe Dateien (a Flux<FilePart>) und ich möchte es auf einige kopieren UPLOAD_ROOT auf dem Server.
Dieses Beispiel stammt aus einem Buch.
Ich kann alles ändern .map Zu .flatMap und umgekehrt und alles funktioniert immer noch. Ich frage mich, was der Unterschied ist.
Können Sie Ihre eigentliche Frage konkreter formulieren? Es gibt mehrere Methoden, auf die Sie sich tatsächlich beziehen map Und flatMap Methoden in Java.
Ja, bitte formulieren Sie die Frage jetzt genauer. Wo genau haben Sie Schwierigkeiten, es zu verstehen? Warum beseitigt ein Blick auf den Quellcode und die Dokumentation nicht die Verwirrung? Gibt es etwas Bestimmtes, das Sie nicht verstehen?
– Zabuzard
5. März 2018 um 16:52
Aus den Dokumenten geht hervor, dass es sich bei beiden um Möglichkeiten handelt, über einen bestimmten Flux zu iterieren map ist synchron und flatMap ist nicht. Aber ich verstehe auch, dass die Funktion, der ich nachgebe map wird asynchron ausgeführt und ich weiß nicht, wann ich welches verwenden soll.
– Schreddern
5. März 2018 um 16:56
… ich werde mit einem konkreten Beispiel aktualisieren.
– Schreddern
5. März 2018 um 16:57
Simon Baslé
map ist für synchrone, nicht blockierende 1-zu-1-Transformationen
flatMap ist für asynchrone (nicht blockierende) 1-zu-N-Transformationen
Der Unterschied ist in der Methodensignatur sichtbar:
map nimmt ein Function<T, U> und gibt a zurück Flux<U>
flatMap nimmt ein Function<T, Publisher<V>> und gibt a zurück Flux<V>
Das ist der wichtigste Hinweis: Sie dürfen pass a Function<T, Publisher<V>> zu einem mapaber es würde nicht wissen, was es damit machen soll Publishersund das würde zu einem führen Flux<Publisher<V>>eine Folge inaktiver Herausgeber.
Andererseits, flatMap erwartet a Publisher<V> für jede T. Es weiß, was es damit machen soll: es abonnieren und seine Elemente in der Ausgabesequenz weitergeben. Daraus ergibt sich der Rückgabetyp Flux<V>: flatMap wird jedes Innere abflachen Publisher<V> in die Ausgabesequenz von alle Die VS.
Zum 1-N-Aspekt:
für jede <T> Eingabeelement, flatMap ordnet es einem zu Publisher<V>. In einigen Fällen (z. B. bei einer HTTP-Anfrage) gibt dieser Herausgeber nur ein Element aus. In diesem Fall sind wir einer Asynchronität ziemlich nahe map.
Aber das ist der degenerierte Fall. Der generische Fall ist, dass a Publisher kann mehrere Elemente emittieren und flatMap funktioniert genauso gut.
Stellen Sie sich zum Beispiel vor, Sie haben eine reaktive Datenbank und erstellen eine FlatMap aus einer Folge von Benutzer-IDs mit einer Anfrage, die den Satz von Benutzer-IDs zurückgibt Badge. Am Ende erhältst du eine Single Flux<Badge> aller Abzeichen aller dieser Benutzer.
Ist map wirklich synchron und nicht blockierend?
Ja: Sie ist synchron in der Art und Weise, wie der Operator sie anwendet (ein einfacher Methodenaufruf, und dann gibt der Operator das Ergebnis aus) und nicht blockierend in dem Sinne, dass die Funktion selbst den Operator, der sie aufruft, nicht blockieren sollte. Mit anderen Worten, es sollte keine Latenz verursachen. Das liegt daran, dass a Flux ist insgesamt immer noch asynchron. Wenn es mitten in der Sequenz blockiert, wirkt es sich auf den Rest aus Flux Verarbeitung oder sogar andere Flux.
Wenn Ihre Kartenfunktion blockiert/Latenz verursacht, aber nicht in die Rückgabe einer konvertiert werden kann Publisherhalten publishOn/subscribeOn um diese Blockierungsarbeit in einem separaten Thread auszugleichen.
Du meintest Karte ist blocking, Rechts? Ich verstehe das auch nicht 1-to-N Wirklich. Können Sie ein Beispiel nennen, wenn das eine gegenüber dem anderen nützlich ist? Ich verstehe, dass ich flatMap verwende, wenn ich erwarte, dass das Ergebnis asynchron ist, weil es die Herausgeber reduziert, sobald das Ergebnis da ist – ist das richtig?
– Schreddern
8. März 2018 um 10:31 Uhr
Nein, die Kartenfunktion sollte nicht blockierend sein (es sei denn, Sie versetzen die Arbeit auch in einem separaten Thread mit publishOn/subscribeOn). das heißt, es wird synchron ausgeführt, sollte aber keine Latenz haben. Die Funktion „flatMap“ ist asynchron und tatsächlich reduziert der Operator die Ergebnisse, sobald sie verfügbar sind
– Simon Baslé
8. März 2018 um 11:34
Ich habe die Antwort bearbeitet, um diese beiden Aspekte zu erläutern + Beispiel für flatMap 1-N
Nur dass Mono jetzt die zusätzliche Feinheit hat, sowohl flatMap (asynchrone 1-zu-1-Transformation) als auch flatMapMany (asynchrone 1-zu-n-Transformation) zu haben.
– Simon Baslé
17. November 2018 um 14:51 Uhr
Raouf Makhlouf
Die FlatMap-Methode ähnelt der Map-Methode mit dem entscheidenden Unterschied, dass der Lieferant, den Sie ihr bereitstellen, eine zurückgeben sollte Mono<T> oder Flux<T>.
Die Verwendung der Kartenmethode würde zu einem führen Mono<Mono<T>>
wohingegen die Verwendung von flatMap zu einem führt Mono<T>.
Dies ist beispielsweise nützlich, wenn Sie zum Abrufen von Daten einen Netzwerkaufruf mit einer Java-API durchführen müssen, die ein Mono zurückgibt, und dann einen weiteren Netzwerkaufruf, der das Ergebnis des ersten benötigt.
// Signature of the HttpClient.get method
Mono<JsonObject> get(String url);
// The two urls to call
String firstUserUrl = "my-api/first-user";
String userDetailsUrl = "my-api/users/details/"; // needs the id at the end
// Example with map
Mono<Mono<JsonObject>> result = HttpClient.get(firstUserUrl).
map(user -> HttpClient.get(userDetailsUrl + user.getId()));
// This results with a Mono<Mono<...>> because HttpClient.get(...)
// returns a Mono
// Same example with flatMap
Mono<JsonObject> bestResult = HttpClient.get(firstUserUrl).
flatMap(user -> HttpClient.get(userDetailsUrl + user.getId()));
// Now the result has the type we expected
Außerdem ermöglicht es eine präzise Fehlerbehandlung:
Es ist wichtig, über map() zu verstehen, dass die Zuordnung synchron durchgeführt wird, da jedes Element vom Quell-Flux veröffentlicht wird. Wenn Sie das Mapping asynchron durchführen möchten, sollten Sie die Operation flatMap() in Betracht ziehen.
Intern wird in einer Flatmap() eine Map()-Operation für Mono ausgeführt, um den String in Player umzuwandeln. Außerdem, subcribeOn() gibt an, dass jedes Abonnement in einem parallelen Thread erfolgen soll.In Abwesenheit von subscribeOn() fungiert flatmap() als synchronisiert.
Die Karte ist für synchrone, nicht blockierende Eins-zu-Eins-Transformationen vorgesehen, während die FlatMap für asynchrone (nicht blockierende) Eins-zu-Viele-Transformationen vorgesehen ist.
Basierend auf dem Bild In Ihrem Flatmap-Beispiel ist es möglich, eine unterschiedliche Anzahl von Eingabe- und Ausgabeelementen zu haben. Könnten Sie bitte ein Beispiel geben? denn in Ihrem Beispiel haben Sie die gleiche Anzahl (3 Eingabeelemente und 3 Ausgabeelemente).
– gstackoverflow
10. Januar um 8:10 Uhr
14514900cookie-checkKarte vs. FlatMap im Reaktoryes
Können Sie Ihre eigentliche Frage konkreter formulieren? Es gibt mehrere Methoden, auf die Sie sich tatsächlich beziehen
map
UndflatMap
Methoden in Java.– Zabuzard
5. März 2018 um 16:43
Ich spreche vom Reactor-Projekt. projectreactor.io/docs/core/release/api/reactor/core/publisher/…
– Schreddern
5. März 2018 um 16:48
Ja, bitte formulieren Sie die Frage jetzt genauer. Wo genau haben Sie Schwierigkeiten, es zu verstehen? Warum beseitigt ein Blick auf den Quellcode und die Dokumentation nicht die Verwirrung? Gibt es etwas Bestimmtes, das Sie nicht verstehen?
– Zabuzard
5. März 2018 um 16:52
Aus den Dokumenten geht hervor, dass es sich bei beiden um Möglichkeiten handelt, über einen bestimmten Flux zu iterieren
map
ist synchron undflatMap
ist nicht. Aber ich verstehe auch, dass die Funktion, der ich nachgebemap
wird asynchron ausgeführt und ich weiß nicht, wann ich welches verwenden soll.– Schreddern
5. März 2018 um 16:56
… ich werde mit einem konkreten Beispiel aktualisieren.
– Schreddern
5. März 2018 um 16:57