Encadenamiento con thenApply y thenCompose
Transforme resultados con thenApply y aplique pasos asíncronos similares a flatMap con thenCompose para evitar futures anidados.
Encadenamiento con thenApply y thenCompose es una lección gratuita de Java Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Java Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Java Academy incluye 4 lecciones en total.
thenApply: transformar el resultado
thenApply(Function) aplica una función síncrona al resultado de un future completado y devuelve un nuevo future con el tipo transformado. No inicia una nueva tarea asíncrona.
CompletableFuture<String> nameFuture = CompletableFuture
.supplyAsync(() -> 42L) // CF<Long>
.thenApply(id -> "User#" + id); // CF<String>
System.out.println(nameFuture.join()); // "User#42"thenApplyAsync: transformar en un hilo
thenApplyAsync ejecuta la función de transformación en el ForkJoinPool (o en un executor proporcionado), lo que libera inmediatamente al hilo que completa el future.
CompletableFuture<String> result = fetchUserAsync()
.thenApplyAsync(user -> serialize(user)); // runs on pool threadthenAccept: consumir sin devolver un valor
thenAccept(Consumer) procesa el resultado, pero devuelve CompletableFuture<Void>. Úselo como último paso de una canalización cuando no necesite pasar un valor al siguiente paso.
fetchUserAsync()
.thenApply(User::getName)
.thenAccept(name -> System.out.println("Hello, " + name));thenRun: ejecutar después de completar
thenRun(Runnable) ejecuta una tarea después de que se complete el future e ignora el resultado. Es útil para cerrar recursos o activar efectos secundarios.
downloadFileAsync(url)
.thenRun(() -> System.out.println("Download complete"));Encadenar varias llamadas a thenApply
Varias llamadas a thenApply forman una canalización. Cada paso recibe la salida del paso anterior.
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.425thenCompose: aplanar futures anidados
thenCompose(Function<T, CompletionStage<U>>) es como flatMap para futures. Evita CompletableFuture<CompletableFuture<T>> al aplanar el future anidado.
// 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 para llamadas asíncronas secuenciales
Use thenCompose cuando cada paso asíncrono dependa del resultado del anterior, de modo que los pasos sean secuenciales y dependan de sus resultados.
fetchUser(userId)
.thenCompose(user -> fetchOrders(user.getId()))
.thenCompose(orders -> computeTotal(orders))
.thenAccept(total -> System.out.println("Total: " + total));thenApply frente a thenCompose
thenApply: asigna T -> U (transformación síncrona). thenCompose: asigna T -> CompletableFuture<U> y aplana el resultado. Use compose cuando el siguiente paso también sea asíncrono.
Gestionar errores intermedios con handle
handle(BiFunction<T, Throwable, U>) se invoca tanto si el future se completó correctamente como si se completó de forma excepcional, lo que permite recuperar o transformar errores a mitad de la canalización.
fetchUser(id)
.thenApply(User::getProfile)
.handle((profile, ex) -> {
if (ex != null) return Profile.empty(); // recover
return profile;
})
.thenAccept(System.out::println);whenComplete: efecto secundario después de cualquier resultado
whenComplete(BiConsumer) se invoca después de la finalización, normal o excepcional, para registrar información o limpiar recursos. A diferencia de handle, no cambia el resultado.
fetchAsync()
.whenComplete((result, ex) -> {
if (ex != null) log.error("Failed", ex);
else log.info("Result: " + result);
});Ejemplo de canalización sin bloqueo
Componga una canalización completamente sin bloqueos: obtenga el usuario, obtenga sus pedidos y calcule un resumen; todos los pasos se ejecutan de forma asíncrona y cada uno depende del anterior.
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());Comprobación rápida
¿Cuándo debe usar thenCompose en lugar de thenApply?
Resumen
thenApply transforma valores síncronos en una canalización. thenCompose encadena pasos asíncronos (es el flatMap de los futures). handle y whenComplete añaden gestión de errores y efectos secundarios. Construya las canalizaciones de izquierda a derecha para facilitar su lectura.
Preguntas frecuentes
¿La lección «Encadenamiento con thenApply y thenCompose» es gratis?
Sí — el texto completo de «Encadenamiento con thenApply y thenCompose» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Java Academy, actualiza a CoddyKit PRO. El curso de Java Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Encadenamiento con thenApply y thenCompose»?
Transforme resultados con thenApply y aplique pasos asíncronos similares a flatMap con thenCompose para evitar futures anidados. Practicas Java Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Java Academy?
No se requiere experiencia previa. Java Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.
¿Cuánto tiempo toma la lección «Encadenamiento con thenApply y thenCompose»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Java Academy?
Sí. Cada lección de Java Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Creación y finalización de CompletableFutures
- Encadenamiento con thenApply y thenCompose
- Combinación de futures: allOf y anyOf
- Gestión de errores y canalización HTTP asíncrona