


Reaktormono Asynchroner Kettenanruf: Holen Sie sich Felder aus einem Mono -Ergebnis und geben Sie sie weiter
Einführung: Herausforderungen reaktionsschneller Kettenaufrufe
Bei responsiven Programmierungen basierend auf dem Projektreaktor stoßen wir häufig auf Szenarien, in denen eine Reihe von asynchronen Operationen erforderlich ist, und das Ergebnis einer Operation ist die Eingabe des nächsten Vorgangs. Zum Beispiel müssen wir zuerst eine Bestellung abfragen und dann die entsprechenden LKW -Informationen basierend auf einer ID in der Bestellung (wie Truckid) abfragen. In diesem Fall ist der Schlüssel, wie Sie die erforderlichen Felder aus dem Ergebnis des ersten Monos elegant extrahieren können, ohne den Hauptfaden zu blockieren und an die Erstellungsfunktion des zweiten Monos zu übergeben. Obwohl der Wert durch direkt unter Verwendung der Block () -Methode erhalten werden kann, verstößt dies gegen das nicht blockierende Prinzip der reaktionsschnellen Programmierung und führt zu Leistungsengpässen und Skalierbarkeitsproblemen.
Szenario Beschreibung: Holen Sie sich LKW -Informationen aus Bestellungen
Angenommen, wir haben zwei Servicemethoden, die Mono bzw. Mono
// Bestelldienst bestellen, bestellen basierend auf id mono <order> order = orderService.getById (UUID -ID); // Fahrzeugservice, erhalten Sie LKW -Mono <truck> Truck = VehicleService.getByTruckid (UUID Truckid);</truck></order>
Unsere Bestellkurs ist wie folgt definiert, die ein Truckid -Feld enthält:
Klassenbestellung { private Uuid -ID; privater Zeichenfolge Name; private Uuid Truckid; // Felder müssen wir extrahieren // ... andere Felder und Methoden}}
Unser Ziel ist: Erhalten Sie zunächst ein Auftragsobjekt, extrahieren Sie dann die Lkw -ID aus diesem Auftragsobjekt und nennen Sie diese LKWID schließlich die Methode des Vehicleservice.getByTruckid (). Der gesamte Prozess muss nicht blockiert sein.
Lösung 1: Verwenden Sie FlatMap für sequentielle Abhängigkeitsoperationen
FlatMap ist ideal, wenn nachfolgende asynchrone Operationen vollständig auf den erfolgreichen Ergebnissen des vorherigen Mono beruhen, und wir kümmern uns nur um die Ausgabe des endgültigen Vorgangs. Der Flatmap -Operator wandelt ein Mono
Arbeitsprinzip: FlatMap empfängt eine Funktion als Parameter. Die Eingabe dieser Funktion ist das vom vorherige Mono (d. H. Das Orderobjekt) emittierte Element, und die Ausgabe ist ein neues Mono (d. H. Mono
Beispielcode:
Import Reactor.core.Publisher.Mono; import Java.util.uuid; // Angenommene Auftrags- und LKW -Klassen und Service -Schnittstellenklassenauftrag {{ private Uuid -ID; privater Zeichenfolge Name; private Uuid Truckid; öffentliche Bestellung (UUID -ID, String -Name, UUID Truckid) { this.id = id; this.name = name; this.truckid = truckid; } public uUid gettruckid () { Rückkehr Truckid; } // ... Getters, Setzer } Klassenwagen { private Uuid -ID; privates Zeichenfolgenmodell; öffentlicher Lkw (UUID -ID, String -Modell) { this.id = id; this.model = Modell; } @Override public String toString () { return "truck {id =" id ", model = '" Modell "'}"; } // ... Getters, Setzer } Schnittstelle ordnerservice { Mono <order> getbyid (uUid id); } Schnittstelle Vehicleservice { Mono <truck> GetByTruckid (uUid truckid); } öffentliche Klasse ReactivechainingExample { privates endgültiger Bestandsservice ordnerservice; private Final VehicaLservice Vehicleservice; public reactiveching -example (orderService orderService, vehicleService Vehicleservice) { this.orderservice = orderService; this.vehicleservice = vehicleService; } /** * Ermitteln Sie nach Erhalt der Bestellung die LKW -Informationen basierend auf dem Truckid in der Bestellung* @param OrderID Order ID * @return mono mit LKW -Informationen enthält Informationen */ public mono <truck> GetTruckbyorderid (uUid orderid) { Mono <order> orderMono = orderService.getById (orderId); // mit FlatMap den LKW aus der Bestellung extrahieren und Vehicleservice anrufen, um LKW zu erhalten Mono <truck> truckmono = orderMono.flatmap (Order -> vehicleService.getByTruckid (Order.GetRuckid ()) ); Rückkehr Truckmono; } public static void main (String [] args) { // Simulation des Dienstes, um orderService mockorderservice = id -> mono.just (Neue Order (ID, "Test Order", uUid.Randomuuid ()) implementieren; VehicleService MockVehiclesservice = Truckid -> Mono.Just (neuer LKW (Truckid, "Volvo FH"); ReactivechainingExample Beispiel = Neue ReactivechainingExample (Mockorderservice, MockVehiclesservice); UUid TestOrderID = uUid.randomuuid (); Beispiel.GetRuckbyorderID (TestOrderID) .abonnieren( Truck -> System.out.println ("erfolgreich erhaltener LKW:" Truck), Fehler -> system.err.println ("Der LKW hat nicht erhalten:" Fehler.getMessage ()) ); // Um den Haupt -Thread zu warten, bis die asynchrone Operation abgeschlossen ist, versuchen Sie es {{{{ Thread.sleep (1000); } catch (InterruptedException e) { Thread.currentThread (). Interrupt (); } } }</truck></order></truck></truck></order>
Im obigen Code zeigt OrderMono.flatMap (Order -> VehicaLService.getByTruckid (order.GetRuckid ()) deutlich, wie die LKWID aus dem Order -Objekt abgerufen und als Parameter an die VehicleService.getByTruckid () -Methode () weitergegeben werden kann, wodurch nicht blockierende Kettenanrufe implementiert werden können.
Lösung 2: Verwenden Sie Mono.zip, um mehrere asynchrone Ergebnisse zu aggregieren
Manchmal brauchen wir nicht nur die endgültigen LKW -Informationen, sondern auch die ursprünglichen Auftragsinformationen, oder die Ergebnisse mehrerer asynchroner Operationen müssen in ein einzelnes Verbindungsergebnis zusammengefasst werden. In diesem Fall ist der Mono.zip -Operator sehr nützlich. Mono.zip kann mehrere mono in einen mono
Wie es funktioniert: Mono.zip wird darauf warten, dass alle teilnehmenden Mono ihre Werte ausstellen. Sobald alle Mono beendet sind und die Werte emittiert sind, verpackt Mono.zip diese Werte in ein Tupel und Emit. Wenn ein teilnehmendes Mono fehlschlägt, schlägt auch der gesamte Postleitzahl fehl.
Beispielcode:
Import Reactor.core.Publisher.Mono; Import Reactor.util.Function.tuple2; // Tuple2 importieren import Java.util.uuid; // ... Bestellung, LKW, ordnerservice, VehicleService -Klassendefinition ist die gleiche wie oben // Definieren Sie eine Ergebnisklasse, um Bestellung und LKW zu verkapseln Klasse orderTruckResult { private Bestellung; Privatwagen; public orderTruckResult (Bestellung, Lkw) { this.order = order; this.truck = truck; } öffentliche Order getorder () { Rücklaufauftrag; } öffentlicher Lkw getTruck () { Rückfahrwagen; } @Override public String toString () { return "orderTruckResult {order =" order.id ", truck =" truck.model "}"; } } öffentliche Klasse ReactiveaggregationExample { privates endgültiger Bestandsservice ordnerservice; private Final VehicaLservice Vehicleservice; public reactiveaggregationexample (orderService orderService, Vehicleservice Vehicleservice) { this.orderservice = orderService; this.vehicleservice = vehicleService; } /** * Holen Sie sich die Bestellung und die entsprechenden LKW -Informationen und aggregieren Sie sie in ein Ergebnisobjekt* @Param Orderid Order ID * @Return Mono mit Bestellung und LKW -Informationen */ public mono <ordertruckresult> getorderandtruck (uUid orderId) { Mono <order> orderMono = orderService.getById (orderId); // Schlüsselschritte: Verwenden Sie Flatmap, um Truckid aus OrderMono zu extrahieren und Truckmono zu erstellen Mono <truck> truckmono = orderMono.flatmap (Order -> vehicleService.getByTruckid (Order.GetRuckid ()) ); // original original ordermono und neu erstellte Truckmono mit mono.zip aggregieren // HINWEIS: Hier ziehen wir den ursprünglichen Ordermono und den Truckmono ab, der davon abhängt. // Das Abonnement von OrderMono wird ausgelöst und das Ergebnis wird verwendet, um einen Truckmono zu erstellen. // Schließlich kombiniert sie, wenn beide Mono Ergebnisse haben, sie kombinieren sie. Mono <ordertruckresult> resultMono = mono.zip (OrderMono, Truckmono) .flatmap (tuple -> { Order order = tuple.gett1 (); // Bestellung bekommen Truck Truck = tuple.gett2 (); // LKW bekommen Return Mono.Just (New OrderTruckResult (Order, LKW)); }); return resultMono; } public static void main (String [] args) { // Simulationsdienst implementiert ordnerservice mockorderservice = id -> mono.just (neue order (id, "test order" id.toString (). Substring (0,4), uuid.randomuuid ())); VehicleService MockVehiclesservice = Truckid -> Mono.Just (neuer LKW (Truckid, Modell- "Truckid.toString (). Substring (0,4)); ReactiveaggregationExample Beispiel = Neue ReactiveaggregationExample (Mockorderservice, MockVehiclesservice); UUid TestOrderID = uUid.randomuuid (); Beispiel.GetOrderAndruck (TestOrderID) .abonnieren( Ergebnis -> System.out.println ("erfolgreich erhaltene Bestellung und LKW:" Ergebnis), Fehler -> System.err.println ("Bestellung und LKW nicht erhalten:" Fehler.getMessage ()) ); versuchen { Thread.sleep (1000); } catch (InterruptedException e) { Thread.currentThread (). Interrupt (); } } }</ordertruckresult></truck></order></ordertruckresult>
In diesem Beispiel verwenden wir zuerst FlatMap, um die Truckid von OrderMono von OrderMono zu holen und den Truckmono zu erstellen. Anschließend verwenden wir Mono.zip (OrderMono, Truckmono), um die Ergebnisse des ursprünglichen Ordermono und des neu erzeugten Truckmono zu verschmelzen. Der ZIP -Betrieb wartet, bis beide Mono erfolgreich abgeschlossen werden können, und verkapulieren dann ihre Ergebnisse in Tuple2. Schließlich verwenden wir erneut FlatMap, um Tuple2 in unser benutzerdefiniertes OrderTruckResult-Objekt umzuwandeln, um es lesbarer und typer sicherer zu machen.
Notizen und Best Practices
- Vermeiden Sie Blockierung von Operationen: Vermeiden Sie immer die Block () -Methode in reaktionsschnellen Ketten. Block () wandelt reaktionsschnelle Streams in Blockierung von Anrufen um und verliert die Vorteile der reaktionsschnellen Programmierung.
- Wählen Sie den richtigen Operator aus:
- Wenn das Ergebnis einer asynchronen Operation der Eingang zum nächsten asynchronen Betrieb ist, verwenden Sie FlatMap.
- Mono.zip (oder flux.zip) wird verwendet, wenn mehrere asynchrone Operationen, die nicht parallel voneinander abhängig sind, und ihre Ergebnisse aggregieren.
- Verwenden Sie Mono.First (), wenn mehrere asynchrone Operationen parallel durchgeführt werden müssen, aber nur das erste abgeschlossene Ergebnis kümmern müssen.
- Benutzerdefinierte Ergebniskapselung: Wenn aggregierte Ergebnisse aus mehreren asynchronen Operationen aggregiert sind, kann die Definition eines dedizierten Pojo (z. B. orderTruckResult) die Kapitulation dieser Ergebnisse, anstatt Tuple direkt zu verwenden, die Lesbarkeit und die Type des Codes verbessern.
- Fehlerbehebung: In praktische Anwendungen stellen Sie jeder Mono -Kette die Fehlerbehandlungslogik hinzu, z.
- Heiße und kalte Fluss verstehen: Mono und Fluss sind standardmäßig kalte Flüsse und werden nur dann ausgeführt, wenn sie abonniert werden. Im Mono.zip -Szenario werden alle teilnehmenden Mono abonniert.
Zusammenfassen
Bei Reaktor -Responsive -Programmierung ist das Extrahieren von Feldern aus den Ergebnissen eines Monos und der Übergabe an nachfolgende asynchrone Operationen eine häufige Voraussetzung. Indem wir die beiden Kernbetreiber-Flatmap und Mono.zip flexibel verwenden, können wir eine effiziente, nicht blockierende und gut strukturierte asynchrone Datenverarbeitungspipeline erstellen. FlatMap ist für nacheinander abhängige Kettenaufrufe geeignet, während mono.zip gut darin ist, die Ergebnisse mehrerer asynchroner Operationen zu aggregieren. Das Beherrschen dieser Muster ist der Schlüssel zum Schreiben von robusten, skalierbaren und reaktionsschnellen Anwendungen.
Das obige ist der detaillierte Inhalt vonReaktormono Asynchroner Kettenanruf: Holen Sie sich Felder aus einem Mono -Ergebnis und geben Sie sie weiter. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undress AI Tool
Ausziehbilder kostenlos

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Stock Market GPT
KI-gestützte Anlageforschung für intelligentere Entscheidungen

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Verwenden Sie den Parameter -cp, um das JAR zum Klassenpfad hinzuzufügen, damit das JVM seine internen Klassen und Ressourcen laden kann, wie z.

Verwenden Sie das Keyword implementiert die Benutzeroberfläche. Die Klasse muss spezifische Implementierungen aller Methoden in der Schnittstelle bereitstellen. Es unterstützt mehrere Schnittstellen und wird von Commas getrennt, um sicherzustellen, dass die Methoden öffentlich sind. Die Standard- und statischen Methoden nach Java 8 müssen nicht umschreiben.

Javaspi ist ein integrierter Service-Erkennungsmechanismus in JDK und implementiert die dynamische Ausdehnung der interface-orientierten Dynamik durch Serviceloader. 1. Definieren Sie die Serviceschnittstelle und erstellen Sie eine Datei mit dem vollständigen Namen der Schnittstelle unter meta-inf/diensten/und schreiben Sie den vollständig qualifizierten Namen der Implementierungsklasse. 2. Verwenden Sie Serviceloader.load (), um die Implementierungsklasse zu laden, und das JVM wird die Konfiguration automatisch lesen und sie instanziieren. 3. Der Schnittstellenvertrag sollte während des Entwurfs, der Unterstützung von Priorität und bedingten Belastung geklärt und die Standardimplementierung bereitstellen. 4. Die Anwendungsszenarien umfassen Mehrzahler-Kanalzugriff und Plug-in-Überprüfung. 5. Achten Sie auf Leistung, Klassenpfad, Ausnahme -Isolation, Thread -Sicherheit und Versionskompatibilität; 6. In Java9 kann die Bereitstellung in Kombination mit Modulsystemen verwendet werden.

Javagenericsprovidecompile-timetypesafetyandeliminatecastingbyallowingtypeparametersonclasses,interfaces,andmethods;wildcards(?,?extendsType,?superType)handleunknowntypeswithflexibility.1.UseunboundedwildcardwhentypeisirrelevantandonlyreadingasObject

In diesem Artikel wird der Mechanismus des Sendens mehrerer HTTP-Anfragen auf demselben TCP-Socket, nämlich die persistierende HTTP-Verbindung (Keep-Alive), eingehend untersucht. Der Artikel verdeutlicht den Unterschied zwischen HTTP/1.x- und HTTP/2-Protokollen, unterstreicht die Bedeutung der serverseitigen Unterstützung für anhaltende Verbindungen und wie die Verbindung korrekt behandelt wird: die Header der Antwort schließen. Durch die Analyse gemeinsamer Fehler und Bereitstellung von Best Practices möchten wir Entwicklern helfen, effiziente und robuste HTTP -Kunden aufzubauen.

In diesem Tutorial wird beschrieben, wie verschachtelte Arraylisten effizient verarbeitet werden können, die andere Arraylisten in Java enthalten und alle seine internen Elemente in ein einzelnes Array verschmelzen. Der Artikel bietet zwei Kernlösungen durch den Flatmap -Betrieb der Java 8 -Stream -API: Zuerst in eine Liste und dann das Ausfüllen des Arrays und das direkte Erstellen eines neuen Arrays, um die Anforderungen verschiedener Szenarien zu erfüllen.

Verwenden Sie die Eigenschaftenklasse, um Java -Konfigurationsdateien einfach zu lesen. 1. Konfiguration. Properties in das Ressourcenverzeichnis, laden Sie es über getClassLoader (). GetResourceAsStream () und rufen Sie die Methode load () auf, um die Datenbankkonfiguration zu lesen. 2. Wenn sich die Datei in einem externen Pfad befindet, verwenden Sie sie mit FileInputStream, um sie zu laden. 3. Verwenden Sie GetProperty (Schlüssel, StandardValue), um fehlende Tasten zu verarbeiten und Standardwerte bereitzustellen, um die Ausnahmeregelung und Eingabeüberprüfung sicherzustellen.
