


Чтобы собрать ответ из двух независимых операций, сохраните обе CompletableFuture, дождитесь их через allOf и прочитайте результаты внутри thenApply. В примере Mentoring.digital одна операция даёт имя, вторая даёт лимит.
Результат allOf имеет тип CompletableFuture<Void>. Он завершится после всех переданных этапов. Значения остаются в исходных объектах. Если хотя бы один этап завершился с исключением, общий результат также завершится с исключением, а обработчик thenApply не выполнится.
Пример рассчитан на Java 17 и новее. В файле оставьте импорт в начале, объявите AccountView внутри класса, а остальные строки поместите в метод main. Вызовы complete здесь заменяют окончания двух запросов. После успешного allOf значения уже готовы, поэтому чтение этих двух результатов внутри обработчика не ждёт их завершения.
import java.util.concurrent.CompletableFuture;
record AccountView(String name, int quota) {}
var name = new CompletableFuture<String>();
var quota = new CompletableFuture<Integer>();
var view = CompletableFuture.allOf(name, quota)
.thenApply(ignored ->
new AccountView(name.join(), quota.join())
);
name.complete("Anna");
quota.complete(5);
System.out.println(view.join());
Замените quota.complete(5) на completeExceptionally с тестовым исключением. Финальный join() для такого результата выбросит CompletionException с причиной. Отдельно проверьте, что ошибочный этап не оставил зависшую операцию. Если частичный ответ допустим, опишите запасное значение для конкретного этапа до объединения.
Сборку ответа из нескольких источников можно отработать на практических занятиях Java. Разбор ошибок и выбора исполнителя для задач уместен на консультации с наставником по Java.