0Pricing
Java Academy · Leçon

Enchaînement avec thenApply et thenCompose

Transformez les résultats avec thenApply et aplatissez les étapes asynchrones avec thenCompose pour éviter les futures imbriquées.

Enchaînement avec thenApply et thenCompose est une leçon Java Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Java Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Java Academy comprend 4 leçons au total.

thenApply : transformer le résultat

thenApply(Function) applique une fonction synchrone au résultat d'une opération asynchrone terminée et renvoie une nouvelle opération asynchrone du type transformé. Il ne démarre pas une nouvelle tâche asynchrone.

CompletableFuture<String> nameFuture = CompletableFuture
    .supplyAsync(() -> 42L)            // CF<Long>
    .thenApply(id -> "User#" + id);    // CF<String>
System.out.println(nameFuture.join()); // "User#42"

thenApplyAsync : transformer sur un fil d'exécution

thenApplyAsync exécute la fonction de transformation dans le ForkJoinPool (ou dans un exécuteur fourni), ce qui libère immédiatement le fil d'exécution qui a terminé l'opération.

CompletableFuture<String> result = fetchUserAsync()
    .thenApplyAsync(user -> serialize(user)); // runs on pool thread

thenAccept : consommer sans renvoyer de résultat

thenAccept(Consumer) traite le résultat, mais renvoie CompletableFuture<Void>. Utilisez-le comme dernière étape d'un pipeline lorsque vous n'avez pas besoin de transmettre une valeur.

fetchUserAsync()
    .thenApply(User::getName)
    .thenAccept(name -> System.out.println("Hello, " + name));

thenRun : exécuter après la fin

thenRun(Runnable) exécute une tâche après la fin de l'opération asynchrone, en ignorant le résultat. C'est utile pour fermer des ressources ou déclencher des effets de bord.

downloadFileAsync(url)
    .thenRun(() -> System.out.println("Download complete"));

Enchaîner plusieurs appels thenApply

Plusieurs appels à thenApply forment un pipeline. Chaque étape reçoit la sortie de l'étape précédente.

CompletableFuture<Double> result = CompletableFuture
    .supplyAsync(() -> "  42.5  ")
    .thenApply(String::trim)
    .thenApply(Double::parseDouble)
    .thenApply(d -> d * 1.21); // apply 21% VAT
System.out.println(result.join()); // 51.425

thenCompose : aplatir des opérations asynchrones imbriquées

thenCompose(Function<T, CompletionStage<U>>) est l'équivalent de flatMap pour les opérations asynchrones. Il évite CompletableFuture<CompletableFuture<T>> en aplatissant l'opération asynchrone imbriquée.

// Wrong with thenApply — returns CF<CF<Order>>:
CompletableFuture<CompletableFuture<Order>> nested =
    fetchUser(id).thenApply(u -> fetchLatestOrder(u.getId()));
// Correct with thenCompose — returns CF<Order>:
CompletableFuture<Order> flat =
    fetchUser(id).thenCompose(u -> fetchLatestOrder(u.getId()));

thenCompose pour des appels asynchrones séquentiels

Utilisez thenCompose lorsque chaque étape asynchrone dépend du résultat de la précédente, afin de rendre les étapes séquentielles et dépendantes de leur résultat.

fetchUser(userId)
    .thenCompose(user -> fetchOrders(user.getId()))
    .thenCompose(orders -> computeTotal(orders))
    .thenAccept(total -> System.out.println("Total: " + total));

thenApply ou thenCompose

thenApply : transforme T -> U de manière synchrone. thenCompose : transforme T -> CompletableFuture<U> et aplatit le résultat. Utilisez compose lorsque l'étape suivante est également asynchrone.

Gérer les erreurs intermédiaires avec handle

handle(BiFunction<T, Throwable, U>) est appelé que l'opération asynchrone se soit terminée normalement ou avec une erreur, ce qui permet de récupérer ou de transformer les erreurs au milieu du pipeline.

fetchUser(id)
    .thenApply(User::getProfile)
    .handle((profile, ex) -> {
        if (ex != null) return Profile.empty(); // recover
        return profile;
    })
    .thenAccept(System.out::println);

whenComplete : effet de bord après n'importe quel résultat

whenComplete(BiConsumer) est appelé après la fin de l'opération (normalement ou avec une erreur) pour la journalisation ou le nettoyage. Contrairement à handle, il ne modifie pas le résultat.

fetchAsync()
    .whenComplete((result, ex) -> {
        if (ex != null) log.error("Failed", ex);
        else            log.info("Result: " + result);
    });

Exemple de pipeline non bloquant

Composez un pipeline entièrement non bloquant : récupérer l'utilisateur, récupérer ses commandes, calculer un récapitulatif — toutes les étapes s'exécutent de manière asynchrone, chacune dépendant de la précédente.

CompletableFuture<String> summary =
    fetchUser(userId)
        .thenCompose(u -> fetchOrders(u.getId()))
        .thenApply(orders -> orders.size() + " orders")
        .exceptionally(ex -> "Error: " + ex.getMessage());
System.out.println(summary.join());

Vérification rapide

Quand devez-vous utiliser thenCompose plutôt que thenApply ?

Bilan

thenApply transforme les valeurs synchrones dans un pipeline. thenCompose enchaîne les étapes asynchrones (l'équivalent de flatMap pour les opérations asynchrones). handle et whenComplete ajoutent la gestion des erreurs et des effets de bord. Construisez les pipelines de gauche à droite pour faciliter la lecture.

Questions Fréquemment Posées

La leçon « Enchaînement avec thenApply et thenCompose » est-elle gratuite ?

Oui — le texte complet de « Enchaînement avec thenApply et thenCompose » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Java Academy, passe à CoddyKit PRO. Le cours Java Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Enchaînement avec thenApply et thenCompose » ?

Transformez les résultats avec thenApply et aplatissez les étapes asynchrones avec thenCompose pour éviter les futures imbriquées. Tu pratiques Java Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Java Academy ?

Aucune expérience préalable n'est requise. Java Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.

Combien de temps prend la leçon « Enchaînement avec thenApply et thenCompose » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Java Academy ?

Oui. Chaque leçon Java Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Créer et terminer des CompletableFutures
  2. Enchaînement avec thenApply et thenCompose
  3. Combiner des futures : allOf et anyOf
  4. Gestion des erreurs et flux HTTP asynchrone
← Retour à Java Academy