Maison  >  Article  >  Java  >  Cette semaine, j'ai appris : CompletableFuture - L'approche Java de la programmation asynchrone

Cette semaine, j'ai appris : CompletableFuture - L'approche Java de la programmation asynchrone

WBOY
WBOYoriginal
2024-08-01 06:51:43855parcourir

This Week I Learnt: CompletableFuture – Java

Cette semaine, je plonge dans CompletableFuture de Java.

En tant que développeur full-stack avec une expérience frontend, gérer des tâches asynchrones est une partie inévitable de mon rôle – requêtes réseau, calculs en arrière-plan, etc. En Java, CompletableFuture est un outil puissant pour gérer ces tâches tout en gardant le thread principal réactif.

Les futurs complets sont à Java ce que les promesses sont à JavaScript.

Si vous êtes familier avec JavaScript, il peut être utile de comprendre ces concepts en faisant des parallèles entre les deux langages. J'aime considérer CompletableFuture comme la version Java d'une promesse. C'est une classe qui représente le résultat éventuel d'une opération asynchrone, que ce résultat soit un succès ou un échec. Introduit dans Java 8 dans le cadre du package java.util.concurrent, il s'agit d'un moyen puissant d'écrire du code non bloquant, avec des méthodes pour enchaîner les opérations et gérer les erreurs, de la même manière que Promises.

Voici une comparaison rapide des deux :

// JavaScript Promise
fetchFromServer()
    .then(data => processData(data))
    .then(result => updateUI(result))
    .catch(error => handleError(error));
// Java CompletableFuture
CompletableFuture.supplyAsync(() -> fetchDataFromServer())
    .thenApply(data -> processData(data))
    .thenAccept(result -> updateUI(result))
    .exceptionally(error -> handleError(error));

Comme illustré ci-dessus, CompletableFuture fournit une syntaxe similaire et chaînable qui permet un code asynchrone propre et lisible.

Envisagez un scénario dans lequel vous devez récupérer les données de profil et l'historique des commandes d'un utilisateur à partir de deux points de terminaison distincts. Vous voudriez éviter de geler l’interface utilisateur en attendant la fin de ces demandes. Voici comment implémenter cela en utilisant CompletableFuture :

CompletableFuture<User> profileFuture = CompletableFuture.supplyAsync(() -> {
    // Fetch user profile from a service
});

CompletableFuture<List<Order>> ordersFuture = CompletableFuture.supplyAsync(() -> {
    // Fetch user orders from another service
});

CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(profileFuture, ordersFuture);

combinedFuture.thenRun(() -> {
    User user = userFuture.join(); 
    List<Order> orders = ordersFuture.join(); 
    displayUserData(user, orders); 
});

Dans cet exemple, nous déclenchons simultanément deux requêtes asynchrones et utilisons allOf pour attendre que les deux se terminent. Une fois qu'ils sont terminés, nous récupérons les résultats et mettons à jour l'interface utilisateur en conséquence, le tout sans bloquer le thread principal.


Étape de chaînage et d'achèvement

CompletableFuture implémente l'interface CompletionStage, qui constitue la base du chaînage des opérations. Chaque méthode thenApply, thenAccept et similaire renvoie un autre CompletionStage, vous permettant de créer des pipelines asynchrones complexes.

De la même manière que nous pouvons enchaîner des promesses en JavaScript lorsque nous avons une séquence de tâches asynchrones à effectuer les unes après les autres, nous pouvons enchaîner des tâches au sein d'un Future Complétable afin de créer une séquence d'opérations asynchrones dépendantes sans tomber dans l'enfer des rappels. . Voici comment procéder :

CompletableFuture.supplyAsync(() -> "Hello")
    .thenApply(result -> result + ", CompletableFuture")
    .thenApply(result -> result + " in Java")
    .thenAccept(System.out::println);

Gestion des exceptions

Là où nous avons .catch() sur un objet Promise, nous avons .exceptionally() sur un Future Completable. Cette méthode gère les exceptions pouvant survenir lors du traitement asynchrone :

CompletableFuture.supplyAsync(() -> {
    if (true) {
        throw new RuntimeException("Exception in CompletableFuture!");
    }
    return "No exception";
}).exceptionally(ex -> {
    System.out.println("Handled exception: " + ex);
    return "Recovered value";
}).thenAccept(System.out::println);

J'espère que cet article vous donnera un bon point de départ pour explorer davantage la classe CompletableFuture.

Liens utiles :

  • Explorations approfondies de la concurrence : un guide pour CompleteableFuture
  • Une introduction complète à la programmation asynchrone en Java – Promesses, rappels et avenir

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn