Î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());
});