programing tip

CompletableFuture |

itbloger 2020. 9. 7. 07:53
반응형

CompletableFuture | thenApply 대 thenCompose


thenApply()와 thenCompose(). 의 차이에 대해 머리를 이해할 수 없습니다 .

그렇다면 누군가 유효한 사용 사례를 제공 할 수 있습니까?

Java 문서에서 :

thenApply(Function<? super T,? extends U> fn)

CompletionStage이 단계가 정상적으로 완료되면 제공된 함수에 대한 인수로이 단계의 결과를 사용하여 실행 되는 new 반환 합니다.

thenCompose(Function<? super T,? extends CompletionStage<U>> fn)

CompletionStage이 단계가 정상적으로 완료되면 제공된 함수에 대한 인수로이 단계를 사용하여 실행 되는 new 반환 합니다.

두 번째 인수 thenCompose는 CompletionStage 확장 thenApply하지 않는 입니다.

누군가 내가 thenApply언제 사용해야하는 경우에 대한 예를 제공 할 수 thenCompose있습니까?


thenApply 동기 매핑 기능이있는 경우 사용됩니다.

CompletableFuture<Integer> future = 
    CompletableFuture.supplyAsync(() -> 1)
                     .thenApply(x -> x+1);

thenCompose비동기 매핑 함수 (예 :를 반환하는 함수)가있는 경우 사용됩니다 CompletableFuture. 그런 다음 중첩 된 퓨처가 아닌 결과와 함께 퓨처를 직접 반환합니다.

CompletableFuture<Integer> future = 
    CompletableFuture.supplyAsync(() -> 1)
                     .thenCompose(x -> CompletableFuture.supplyAsync(() -> x+1));

Java 9의 업데이트 된 Javadocs는 아마도 더 나은 이해를 도울 것입니다.

thenApply

<U> CompletionStage<U> thenApply​(Function<? super T,? extends U> fn)

CompletionStage이 단계가 정상적으로 완료되면 제공된 함수에 대한 인수로이 단계의 결과를 사용하여 실행 되는 new 반환 합니다.

이 방법은 유사 Optional.map하고 Stream.map.

CompletionStage예외적 인 완료를 다루는 규칙 문서를 참조하십시오 .

thenCompose

<U> CompletionStage<U> thenCompose​(Function<? super T,? extends CompletionStage<U>> fn)

주어진 함수에 의해 반환 된 CompletionStage것과 동일한 값으로 완성 된 new CompletionStage반환합니다.

이 단계가 정상적으로 완료되면 주어진 함수가이 단계의 결과를 인수로 사용하여 호출되어 다른 CompletionStage. 해당 단계가 정상적으로 완료되면 CompletionStage이 메서드 에서 반환 된 값이 동일한 값으로 완료됩니다.

진행을 보장하기 위해 제공된 함수는 결과의 최종 완료를 정렬해야합니다.

이 방법은 유사 Optional.flatMap하고 Stream.flatMap.

CompletionStage예외적 인 완료를 다루는 규칙 문서를 참조하십시오 .


@Joe C가 올린 답변이 오해의 소지가 있다고 생각합니다.

나 사이의 차이를 설명하려고하자 thenApplythenCompose예와 함께.

두 가지 방법이 있다고 가정 해 봅시다 : getUserInfo(int userId)and getUserRating(UserInfo userInfo):

public CompletableFuture<UserInfo> userInfo = getUserInfo(userId)

public CompletableFuture<UserRating> getUserRating(UserInfo)

두 메서드 반환 유형은 모두 CompletableFuture.

We want to call getUserInfo() first, and on its completion, call getUserRating() with the resulting UserInfo.

On the completion of getUserInfo() method, let's try both thenApply and thenCompose. The difference is in the return types:

CompletableFuture<CompletableFuture<UserRating>> f =
    userInfo.thenApply(this::getUserRating);

CompletableFuture<UserRating> relevanceFuture =
    userInfo.thenCompose(this::getUserRating);

thenCompose() works like Scala's flatMap which flattens nested futures.

thenApply() returned the nested futures as they were, but thenCompose() flattened the nested CompletableFutures so that it is easier to chain more method calls to it.


thenApply and thenCompose is called on a CompletableFuture and does something with its result by supplying a Function. thenApply and thenCompose both return a CompletableFuture as their own result, such that you can chain multiple thenApply or thenCompose, each one would have a Function doing something to the result of the last Function.

This Function sometimes needs to do something synchronously, and return a result, in which case thenApply should be used.

CompletableFuture.completedFuture(1)
    .thenApply((x)->x+1) // adding one to the result synchronously
    .thenApply((x)->System.println(x));

You may also do something asynchronous in this Function, and this asynchronous thing you do should return a CompletionStage. The next Function in the chain is not interested in getting a CompletionStage as input, but rather the result of that CompletionStage. So then you should use thenCompose.

// addOneAsync may be implemented by using another thread, or calling a remote method
// CompletableFuture<Integer> addOneAsync(int input);
CompletableFuture.completedFuture(1)
    .thenCompose((x)->addOneAsync(x)) // doing something asynchronous
    .thenApply((x)->System.println(x));

In Javascript, Promise.then can accept a function, that either returns a value or a Promise of a value. In Java because of type rules, the two functions have to be distinctly typed, ie. (Function<? super T,? extends U> fn and Function<? super T,? extends CompletionStage<U>> fn. (or that Java has to do some type checking to do something special if you return a CompletionStage, but they chose the former) The end result being, Promise.then is implemented in two parts thenApply and thenCompose.

You can also read my answer about thenApplyAsync if that is confusing to you.

참고URL : https://stackoverflow.com/questions/43019126/completablefuture-thenapply-vs-thencompose

반응형