Связка CompletableFuture в Java
thenApply получает готовое значение и
сразу возвращает новое. Если следующий шаг сам
асинхронный и отдаёт ещё один
CompletableFuture, вложенность ломает
читаемость. Метод thenCompose принимает
Function<T, CompletableFuture<U>>
и «разворачивает» внутренний объект в один
плоский CompletableFuture<U>.
Сначала id заказа, затем асинхронная загрузка суммы по этому id:
import java.util.concurrent.CompletableFuture;
public class Main {
static CompletableFuture<Integer> loadTotal(int id) {
return CompletableFuture.supplyAsync(() -> id * 100);
}
public static void main(String[] args) {
int total = CompletableFuture
.supplyAsync(() -> 5)
.thenCompose(Main::loadTotal)
.join();
System.out.println(total);
}
}
Два независимых запроса можно дождаться вместе
через thenCombine. Он принимает второй
CompletableFuture и
BiFunction<T, U, V>, когда оба
источника успешно завершились:
import java.util.concurrent.CompletableFuture;
public class Main {
public static void main(String[] args) {
CompletableFuture<Integer> price =
CompletableFuture.supplyAsync(() -> 120);
CompletableFuture<Integer> qty =
CompletableFuture.supplyAsync(() -> 3);
int sum = price.thenCombine(qty, (p, q) -> p * q).join();
System.out.println(sum);
}
}
thenCompose выбирают для последовательных
зависимых шагов, thenCombine для параллельных
веток с общим финалом. Асинхронные аналоги
thenComposeAsync и thenCombineAsync
снова принимают необязательный Executor.
Из строки "8" асинхронно получите число,
затем асинхронно умножьте его на 2.
Отдельно запустите две асинхронные задачи с числами
4 и 6, сложите их результаты.