


Réacteur mono asynchrone Call Call: Obtenez les champs d'un résultat mono et passez-les
Introduction: défis des appels de chaîne réactifs
Dans une programmation réactive basée sur le réacteur de projet, nous rencontrons souvent des scénarios où une série d'opérations asynchrones est nécessaire, et le résultat d'une opération est l'entrée de l'opération suivante. Par exemple, nous pouvons d'abord devoir interroger une commande, puis interroger les informations de camion correspondantes sur la base d'un ID dans la commande (comme TruckID). Dans ce cas, la clé est de savoir comment extraire élégamment les champs requis du résultat du premier mono sans bloquer le fil principal et le passer à la fonction de création du deuxième mono. Bien que la valeur puisse être obtenue en utilisant directement la méthode Block (), cela viole le principe non bloquant de la programmation réactive et entraînera des goulots d'étranglement de performances et des problèmes d'évolutivité.
Description du scénario: obtenir des informations sur les commandes du camion
Supposons que nous ayons deux méthodes de service, respectivement Mono
// Service de commande, obtenez l'ordre en fonction de l'ID mono <ord> ORDANDE = ORDERSERVICE.GETBYID (UUID ID); // Service de véhicule, obtenir un camion mono <ruck> Truck = VehicleService.getByTruckid (UUID TruckID);</ruck></ord>
Notre classe de commande est définie comme suit, qui contient un champ Truckid:
classe Order { ID UUID privé; nom de chaîne privé; Uuid Truckid privé; // Fields Nous devons extraire // ... Autres champs et méthodes}
Notre objectif est: Obtenez d'abord un objet de commande, puis extraire le Truckid de cet objet de commande, et enfin utilisez ce Truckid pour appeler le véhiculeservice.getByTruckId (). L'ensemble du processus doit être non bloquant.
Solution 1: Utilisez FlatMap pour les opérations de dépendance séquentielle
FlatMap est idéal lorsque les opérations asynchrones ultérieures reposent entièrement sur les résultats réussis du mono précédent et nous ne nous soucions que de la sortie de l'opération finale. L'opérateur FlatMap convertit un mono
Principe de travail: FlatMap reçoit une fonction en tant que paramètre. L'entrée de cette fonction est l'élément émis par le mono précédent (c'est-à-dire l'objet de commande), et la sortie est un nouveau mono (c'est-à-dire mono
Exemple de code:
Importer Reactor.Core.Publisher.Mono; import java.util.uuid; // Classes de commande et de camion supposées et classe d'interface de service Ordre { ID UUID privé; nom de chaîne privé; Uuid Truckid privé; Ordre publique (ID UUID, nom de chaîne, UUID Truckid) { this.id = id; this.name = name; this.TruckId = Truckid; } public uuid getTruckid () { Retour Truckid; } // ... Getters, setters } camion de classe { ID UUID privé; modèle de chaîne privé; camion public (ID UUID, modèle de chaîne) { this.id = id; this.model = modèle; } @Outrepasser public String toString () { return "Truck {id =" id ", modèle = '" modèle "'}"; } // ... Getters, setters } Interface OrderService { Mono <order> GetById (UUID ID); } Interface VehicleService { Mono <cruck> GetbyTruckid (UUID Truckid); } classe publique ReactiveChainingExample { Ordiction d'ordérer l'ordre final privé; Véhicule final privé pour véhicules de véhicules; Public ReactiveChainingExample (OrderService OrderService, véhiculeservice VehicleService) { this.orderService = OrderService; this.veHiclesService = VehicleService; } / ** * Après avoir obtenu la commande, obtenez les informations sur le camion en fonction du caminid dans la commande * @param * @return mono contenant des informations sur les camions * / public mono <ruck> getTruckByOrderId (uUid OrderId) { Mono <order> ORDERMONO = ORDERSERVICE.GETBYID (ORDERID); // Utilisez FlatMap pour extraire le camion de la commande et appelez le service de véhicules pour obtenir un camion Mono <ruck> Truckmono = OrderMono.flatMap (Order -> VehicleService.getByTruckId (Order.GetTruckId ()) )); RETOUR TRUCKMONO; } public static void main (String [] args) { // Simuler le service pour implémenter OrderService Mockorderservice = id -> Mono.Just (New Order (ID, "Test Order", uUid.randomuuid ())); VehicleService MockVeHculesVice = Truckid -> Mono.Just (New Truck (Truckid, "Volvo FH")); ReactiveChainingExample Exemple = new ReactiveChainingExample (Mockorderservice, mockVeHculesService); UUId testOrderId = uUid.randomuuid (); Exemple.getTruckByOrderId (TestOrderId) .s'abonner( Truck -> System.out.println ("Truck obtenu avec succès:" Truck), Error -> System.err.println ("Impossible d'obtenir le camion:" Error.GetMessage ()) )); // Afin de faire en sorte que le fil principal attend la fonctionnalité de l'opération asynchrone, essayez { Thread.Sleep (1000); } catch (InterruptedException e) { Thread.currentThread (). Interrupt (); } } }</ruck></order></ruck></cruck></order>
Dans le code ci-dessus, OrderMono.flatMap (Order -> VehicleService.getByTruckId (Order.GetTruckId ())) montre clairement comment obtenir le camion de l'objet de commande et le passer comme paramètre au véhiculeservice.getByTruckId (), mettant ainsi en œuvre des appels de chaîne non bloquants.
Solution 2: Utilisez mono.zip pour agréger plusieurs résultats asynchrones
Parfois, nous avons non seulement besoin des informations finales du camion, mais aussi les informations d'ordre d'origine, ou les résultats de plusieurs opérations asynchrones doivent être fusionnées dans un seul résultat composé. Dans ce cas, l'opérateur mono.zip est très utile. Mono.zip peut fusionner plusieurs mono dans un mono
Comment cela fonctionne: Mono.zip attendra que tous les mono participants émettent leurs valeurs. Une fois que tous les mono sont terminés et que les valeurs sont émises, mono.zip emballera ces valeurs en tuple et émettra. Si un mono participant échoue, l'intégralité de l'opération ZIP échouera également.
Exemple de code:
Importer Reactor.Core.Publisher.Mono; importer reactor.util.function.tuple2; // Importer Tuple2 import java.util.uuid; // ... commande, camion, service d'order classe OrderTruckResult { Ordre de commande privée; camion de camion privé; OrderTrUckResult publique (commande de commande, camion de camion) { this.order = ordre; this.truck = camion; } Ordre public GetOrder () { Ordre de retour; } camion public getTruck () { camion de retour; } @Outrepasser public String toString () { return "OrderTrUckResult {Order =" Order.id ", Truck =" Truck.Model "}"; } } classe publique reactiveAgggationExample { Ordiction d'ordérer l'ordre final privé; Véhicule final privé pour véhicules de véhicules; ReactiveAggationgation Exemple (OrderService OrderService, véhiculeservice VehicleService) { this.orderService = OrderService; this.veHiclesService = VehicleService; } / ** * Obtenez la commande et les informations de camion correspondantes et les agréger dans un objet résultat * @param ordonnance ID de commande * @return mono contenant des informations sur l'ordre et les camions * / public mono <ordertruckresult> GetOrderAndTruck (uUid OrderId) { Mono <order> ORDERMONO = ORDERSERVICE.GETBYID (ORDERID); // Étapes de clé: Utilisez FlatMap pour extraire TruckID de OrderMono et créez Truckmono Mono <ruck> Truckmono = OrderMono.flatMap (Order -> VehicleService.getByTruckId (Order.GetTruckId ()) )); // agrégait l'OrderMono d'origine et Truckmono nouvellement créé à l'aide de mono.zip // Remarque: Ici, nous zipons l'OrderMono d'origine et le Truckmono qui en dépendent. // L'abonnement d'OrderMono sera déclenché et le résultat sera utilisé pour créer un Truckmono. // Enfin, lorsque les deux mono ont des résultats, ZIP les combinera. Mono <ordertruckresult> ResultMono = mono.zip (OrderMono, Truckmono) .flatMap (Tuple -> { Order Order = Tuple.gett1 (); // Obtenez la commande Truck Truck = Tuple.gett2 (); // Obtenez un camion RETOUR MONO.JUST (New OrderTruckResult (Order, Truck)); }); Retour ResultMono; } public static void main (String [] args) { // Le service de simulation implémente OrderService Mockorderservice = id -> mono.Just (New Order (id, "Test Order" id.ToString (). Substring (0,4), uuid.randomuuid ())); VehicleService mockVeHculesService = Truckid -> mono.Just (New Truck (Truckid, "Model-" Truckid.ToString (). Substring (0,4))); ReactiveAggregationExample Example = new ReactiveAggEggationExample (mockorderservice, mockVeHculesService); UUId testOrderId = uUid.randomuuid (); Exemple.getOrderAndTruck (TestOrderId) .s'abonner( Résultat -> System.out.println ("Ordre obtenu avec succès:" Résultat), Erreur -> System.err.println ("Impossible d'obtenir la commande et le camion:" Error.GetMessage ()) )); essayer { Thread.Sleep (1000); } catch (InterruptedException e) { Thread.currentThread (). Interrupt (); } } }</ordertruckresult></ruck></order></ordertruckresult>
Dans cet exemple, nous utilisons d'abord FlatMap pour obtenir le Truckid de OrderMono et créons le Truckmono. Ensuite, nous utilisons mono.zip (OrderMono, Truckmono) pour fusionner les résultats de l'OrderMono d'origine et du Truckmono nouvellement généré. L'opération ZIP attendra que les deux mono se terminent avec succès, puis encapsulent leurs résultats dans Tuple2. Enfin, nous utilisons à nouveau FlatMap pour convertir Tuple2 en notre objet OrderTruckRuck personnalisé pour le rendre plus lisible et à sécurité.
Notes et meilleures pratiques
- Évitez les opérations de blocage: Évitez toujours d'utiliser la méthode Block () dans les chaînes réactives. Block () convertira des flux réactifs en blocs de blocage, perdant les avantages de la programmation réactive.
- Sélectionnez l'opérateur correct:
- Lorsque le résultat d'une opération asynchrone est l'entrée de l'opération asynchrone suivante, utilisez FlatMap.
- Mono.zip (ou flux.zip) est utilisé lorsque plusieurs opérations asynchrones qui ne sont pas interdépendantes en parallèle et agrégent leurs résultats.
- Utilisez mono.first () lorsque plusieurs opérations asynchrones doivent être effectuées en parallèle, mais ne se soucient que du premier résultat terminé.
- Encapsulation des résultats personnalisés: lorsqu'il est agrégé résulte de plusieurs opérations asynchrones, définissant un POJO dédié (tel que OrderTruckResult) pour encapsuler ces résultats, au lieu d'utiliser directement des tuples, peut améliorer la lisibilité et le type de sécurité du code.
- Gestion des erreurs: Dans les applications pratiques, assurez-vous d'ajouter la logique de gestion des erreurs à chaque chaîne mono, comme l'utilisation d'OnerrorResume, ONERRORRETUR ou Doonerror.
- Comprendre le flux chaud et froid: le mono et le flux sont des flux à froid par défaut et ne seront exécutés que lorsqu'ils sont abonnés. Dans le scénario mono.zip, tous les mono participants seront abonnés.
Résumer
Dans la programmation sensible aux réacteurs, l'extraction des champs des résultats d'un mono et les transmettre à des opérations asynchrones ultérieures est une exigence commune. En utilisant de manière flexible les deux opérateurs de noyau FlatMap et Mono.zip, nous pouvons construire un pipeline de traitement des données asynchrones efficace, non bloquant et bien structuré. FlatMap convient aux appels de chaîne séquentiellement dépendants, tandis que mono.zip est bon pour agréger les résultats de plusieurs opérations asynchrones. La maîtrise de ces modèles est la clé pour écrire des applications robustes, évolutives et réactives.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Outils d'IA chauds

Undress AI Tool
Images de déshabillage gratuites

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Stock Market GPT
Recherche d'investissement basée sur l'IA pour des décisions plus intelligentes

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Utilisez le paramètre -cp pour ajouter le pot au ClassPath, afin que le JVM puisse charger ses classes et ressources internes, telles que Java-Cplibrary.jarcom.example.main, qui prend en charge plusieurs pots séparés par semi-colons ou couleurs, et peut également être configuré via des variables d'environnement de ClassPath Variables ou Manifest.mf.

UseFile.CreateEnewFile () toCreateaFileOnlyiFitDoOesn’texist, EvitingoverWriting; 2.Preferfiles.CreateFile () FromNio.2Formodern, SafeFilecreationThatFailSiftheFileExists; 3.UseFileWriterorPrintwriterWistereAdMedimMedimate

Utilisez le mot-clé Implements pour implémenter l'interface. La classe doit fournir des implémentations spécifiques de toutes les méthodes dans l'interface. Il prend en charge plusieurs interfaces et est séparé par des virgules pour s'assurer que les méthodes sont publiques. Les méthodes par défaut et statiques après Java 8 n'ont pas besoin d'être réécrites.

Javaspi est un mécanisme de découverte de service intégré dans JDK et met en œuvre une expansion dynamique orientée vers l'interface via ServiceLoader. 1. Définissez l'interface de service et créez un fichier nommé avec le nom complet de l'interface sous Meta-Inf / Services /, et écrivez le nom entièrement qualifié de la classe d'implémentation; 2. Utilisez ServiceLoader.Load () pour charger la classe d'implémentation, et le JVM lira automatiquement la configuration et l'instanciera; 3. Le contrat d'interface doit être clarifié lors de la conception, de la priorité de support et du chargement conditionnel et fournit une implémentation par défaut; 4. Les scénarios d'application incluent l'accès au canal multi-paiement et la vérification du plug-in; 5. Faites attention aux performances, à ClassPath, à l'isolement des exceptions, à la sécurité des fils et à la compatibilité des versions; 6. Dans Java9, la fourniture peut être utilisée en combinaison avec des systèmes de modules.

JavagenerricsprovideCompile-TimetypePesafetyAndeliminateStingByAllowingTypeParameTersersonClasses, Interfaces et Methods; Wildcards (?,

Cet article explore en profondeur le mécanisme d'envoi de plusieurs demandes HTTP sur la même prise TCP, à savoir la connexion persistante HTTP (Keep-Alive). L'article clarifie la différence entre les protocoles HTTP / 1.x et HTTP / 2, souligne l'importance de la prise en charge côté serveur pour les connexions persistantes et comment gérer correctement la connexion: fermer les en-têtes de réponse. En analysant les erreurs courantes et en fournissant les meilleures pratiques, nous visons à aider les développeurs à construire des clients HTTP efficaces et robustes.

Utilisez la classe Properties pour lire facilement les fichiers de configuration Java. 1. Mettez Config.Properties dans le répertoire de ressources, chargez-le via getClassOader (). GetResourceAsStream () et appelez la méthode Load () pour lire la configuration de la base de données. 2. Si le fichier est dans un chemin externe, utilisez FileInputStream pour le charger. 3. Utilisez GetProperty (Key, DefaultValue) pour gérer les clés manquantes et fournir des valeurs par défaut pour garantir la gestion des exceptions et la vérification des entrées.

Ce didacticiel détaille comment traiter efficacement les listes de table imbriquées contenant d'autres listes de tableaux en Java et fusionner tous ses éléments internes en un seul tableau. L'article fournira deux solutions de base grâce à l'opération FlatMap de l'API Java 8 Stream: aplatissant d'abord une liste, puis remplissant le tableau, et créant directement un nouveau tableau pour répondre aux besoins de différents scénarios.
