Programare Asincronă cu CompletableFuture și Reactive Streams (Flow API) în Java în Java

Ghid complet pentru compoziția asincronă în Java: chaining funcțional cu CompletableFuture (thenApply, thenCompose, allOf), tratarea excepțiilor cu exceptionally și standardul Flow API pentru Reactive Streams.

Sintaxă
CompletableFuture.supplyAsync(...).thenCompose(...).exceptionally(...) | Flow.Publisher

Înainte de apariția clasei CompletableFuture, lucrul cu fire asincrone se limita la interfața Future, a cărei metodă de citire a rezultatului (future.get()) era rigidă și blocantă. CompletableFuture aduce modelul de programare funcțională asincronă (Monadic Composition), permițând înlănțuirea operațiilor non-blocante sub formă de conducte reactive (pipelines).

Înlănțuirea Asincronă a Serviciilor cu CompletableFuture
import java.util.concurrent.CompletableFuture;

public class AsyncPipelineDemo {

    public static void main(String[] args) {
        // Inițiem o conductă asincronă pe ForkJoinPool comun:
        CompletableFuture pipeline = CompletableFuture.supplyAsync(() -> {
            // Pasul 1: Interogare asincronă utilizator
            return "user:4021";
        })
        .thenApply(userId -> {
            // Pasul 2: Transformare de date (mapare sincronă)
            return userId.toUpperCase();
        })
        .thenCompose(userFormatat -> {
            // Pasul 3: Apelează o altă metodă asincronă (flatMap)
            return descarcaSoldContAsync(userFormatat);
        })
        .exceptionally(eroare -> {
            // Pasul 4: Recuperare elegantă în caz de eroare pe oricare dintre pași
            System.err.println("Eroare pe conductă: " + eroare.getMessage());
            return "Sold indisponibil (Fallback)";
        });

        // Când rezultatul devine disponibil, îl afișăm:
        pipeline.thenAccept(rezultatFinal -> {
            System.out.println("Rezultat final procesat: " + rezultatFinal);
        });

        // Așteptăm pentru finalizarea procesării asincrone în demo:
        pipeline.join();
    }

    private static CompletableFuture descarcaSoldContAsync(String user) {
        return CompletableFuture.supplyAsync(() -> "Sold cont pentru " + user + ": 1.250,00 EUR");
    }
}

Combinarea Concomitentă cu CompletableFuture.allOf()

Dacă trebuie să așteptați finalizarea în paralel a mai multor sarcini asincrone complet independente înainte de a agrega rezultatele:

CompletableFuture taskA = CompletableFuture.supplyAsync(() -> "Serviciu A");
CompletableFuture taskB = CompletableFuture.supplyAsync(() -> "Serviciu B");

// Agregare paralelă:
CompletableFuture.allOf(taskA, taskB).thenRun(() -> {
    System.out.println("Ambele servicii au răspuns cu succes: " + taskA.join() + ", " + taskB.join());
});