0Pricing
Java Academy · 강의

thenApply와 thenCompose를 사용한 연결

thenApply로 결과를 변환하고 thenCompose로 비동기 단계를 flatMap하여 중첩 퓨처를 피합니다.

thenApply와 thenCompose를 사용한 연결은(는) CoddyKit의 무료 Java Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Java Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

thenApply: 결과 변환

thenApply(Function)은 완료된 퓨처의 결과에 동기 함수를 적용하여 변환된 유형의 새 퓨처를 반환합니다. 새 비동기 작업을 시작하지는 않습니다.

CompletableFuture<String> nameFuture = CompletableFuture
    .supplyAsync(() -> 42L)            // CF<Long>
    .thenApply(id -> "User#" + id);    // CF<String>
System.out.println(nameFuture.join()); // "User#42"

thenApplyAsync: 스레드에서 변환

thenApplyAsync는 ForkJoinPool 또는 제공된 실행기에서 변환 함수를 실행하여, 완료를 처리한 스레드를 즉시 해제합니다.

CompletableFuture<String> result = fetchUserAsync()
    .thenApplyAsync(user -> serialize(user)); // runs on pool thread

thenAccept: 반환 없이 소비

thenAccept(Consumer)는 결과를 처리하지만 CompletableFuture<Void>를 반환합니다. 값을 다음 단계로 전달할 필요가 없을 때 처리 흐름의 마지막 단계로 사용하십시오.

fetchUserAsync()
    .thenApply(User::getName)
    .thenAccept(name -> System.out.println("Hello, " + name));

thenRun: 완료 후 실행

thenRun(Runnable)은 결과를 무시하고 퓨처가 완료된 후 작업을 실행합니다. 리소스를 닫거나 부수 효과를 발생시키는 데 적합합니다.

downloadFileAsync(url)
    .thenRun(() -> System.out.println("Download complete"));

여러 thenApply 호출 연결

여러 thenApply 호출이 하나의 처리 흐름을 구성합니다. 각 단계는 이전 단계의 출력을 받습니다.

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.425

thenCompose: 중첩 퓨처 평탄화

thenCompose(Function<T, CompletionStage<U>>)는 퓨처에 대한 flatMap과 같습니다. 중첩된 퓨처를 평탄화하여 CompletableFuture<CompletableFuture<T>>가 생성되는 것을 방지합니다.

// 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

각 비동기 단계가 이전 단계의 결과에 의존하여 단계가 순차적으로 실행되고 결과에 따라 진행되어야 할 때 thenCompose를 사용하십시오.

fetchUser(userId)
    .thenCompose(user -> fetchOrders(user.getId()))
    .thenCompose(orders -> computeTotal(orders))
    .thenAccept(total -> System.out.println("Total: " + total));

thenApply와 thenCompose 비교

thenApply: T -> U를 매핑합니다(동기 변환). thenCompose: T -> CompletableFuture<U>를 매핑하고 평탄화합니다. 다음 단계도 비동기일 때 compose를 사용하십시오.

handle로 중간 오류 처리

handle(BiFunction<T, Throwable, U>)은 퓨처가 정상적으로 완료되었는지 예외와 함께 완료되었는지에 관계없이 호출되므로, 처리 흐름 중간에서 오류를 복구하거나 변환할 수 있습니다.

fetchUser(id)
    .thenApply(User::getProfile)
    .handle((profile, ex) -> {
        if (ex != null) return Profile.empty(); // recover
        return profile;
    })
    .thenAccept(System.out::println);

whenComplete: 모든 결과 이후 부수 효과 실행

whenComplete(BiConsumer)는 정상 완료인지 예외 완료인지에 관계없이 완료 후 로그 기록이나 정리를 위해 호출됩니다. handle과 달리 결과를 변경하지 않습니다.

fetchAsync()
    .whenComplete((result, ex) -> {
        if (ex != null) log.error("Failed", ex);
        else            log.info("Result: " + result);
    });

비블로킹 처리 흐름 예시

완전히 비블로킹인 처리 흐름을 구성해 보십시오. 사용자를 가져오고, 사용자의 주문을 가져온 다음, 요약을 계산합니다. 모든 단계는 비동기적으로 실행되며 각 단계는 이전 단계에 의존합니다.

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

빠른 확인

thenApply 대신 thenCompose를 사용해야 하는 경우는 언제입니까?

복습

thenApply는 처리 흐름에서 동기 값을 변환합니다. thenCompose는 비동기 단계를 연결합니다(퓨처에 대한 flatMap). handle과 whenComplete는 오류 처리와 부수 효과를 추가합니다. 가독성을 위해 처리 흐름을 왼쪽에서 오른쪽으로 구성하십시오.

자주 묻는 질문

“thenApply와 thenCompose를 사용한 연결” 강의는 무료인가요?

네 — “thenApply와 thenCompose를 사용한 연결” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Java Academy 강의 전체를 잠금 해제할 수 있습니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“thenApply와 thenCompose를 사용한 연결”에서 뭘 배우나요?

thenApply로 결과를 변환하고 thenCompose로 비동기 단계를 flatMap하여 중첩 퓨처를 피합니다. 브라우저에서 직접 실행하는 실습 코드로 Java Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Java Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Java Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.

“thenApply와 thenCompose를 사용한 연결” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Java Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Java Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. CompletableFutures 생성과 완료
  2. thenApply와 thenCompose를 사용한 연결
  3. 퓨처 결합: allOf와 anyOf
  4. 오류 처리와 비동기 HTTP 파이프라인
← Java Academy(으)로 돌아가기