Метод thenCompose
Метод thenCompose класса CompletableFuture применяется
для последовательного объединения двух асинхронных вычислений.
В первый параметр мы передаем функцию, которая принимает результат
текущего CompletableFuture и возвращает новый
CompletableFuture. В отличие от метода thenApply,
который возвращает обычное значение, thenCompose
«разворачивает» вложенный CompletableFuture и возвращает
уже плоский результат. Это позволяет строить цепочки зависимых
асинхронных операций без вложенных структур.
Синтаксис
CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn)
Пример
Давайте создадим первый CompletableFuture, который вернет
строку "abcde", а затем с помощью thenCompose
выполним вторую асинхронную операцию, возвращающую длину этой строки:
import java.util.concurrent.CompletableFuture;
public class Main
{
public static void main(String[] args)
{
CompletableFuture<String> first = CompletableFuture.supplyAsync(() -> "abcde");
CompletableFuture<Integer> res = first.thenCompose(
str -> CompletableFuture.supplyAsync(() -> str.length())
);
System.out.println(res.join());
}
}
Результат выполнения кода:
5
Пример
Давайте свяжем две операции, каждая из которых возвращает
свой CompletableFuture. Первая формирует список,
вторая считает количество элементов в нем:
import java.util.List;
import java.util.concurrent.CompletableFuture;
public class Main
{
public static void main(String[] args)
{
CompletableFuture<List<String>> first = CompletableFuture.supplyAsync(
() -> List.of("a", "b", "c", "d", "e")
);
CompletableFuture<Integer> res = first.thenCompose(
list -> CompletableFuture.supplyAsync(() -> list.size())
);
System.out.println(res.join());
}
}
Результат выполнения кода:
5
Пример
Давайте сравним поведение thenApply и thenCompose.
Метод thenApply вернул бы вложенный
CompletableFuture<CompletableFuture<Integer>>,
а thenCompose сразу возвращает плоский результат:
import java.util.concurrent.CompletableFuture;
public class Main
{
public static void main(String[] args)
{
CompletableFuture<String> first = CompletableFuture.supplyAsync(() -> "12345");
CompletableFuture<CompletableFuture<Integer>> nested = first.thenApply(
str -> CompletableFuture.supplyAsync(() -> str.length())
);
CompletableFuture<Integer> flat = first.thenCompose(
str -> CompletableFuture.supplyAsync(() -> str.length())
);
System.out.println(nested.join().join());
System.out.println(flat.join());
}
}
Результат выполнения кода:
5
5
Смотрите также
-
метод
thenApply,
который преобразует результат без разворачивания -
метод
supplyAsync,
который создает асинхронную задачу с результатом -
метод
thenAccept,
который потребляет результат без возврата значения -
метод
join,
который ожидает завершения цепочки