Java CompletableFuture | thenApply 与 thenCompose
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43019126/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
CompletableFuture | thenApply vs thenCompose
提问by GuyT
I can't get my head around the difference between thenApply(
) and thenCompose()
.
我无法理解thenApply(
) 和thenCompose()
.
So, could someone provide a valid use case?
那么,有人可以提供一个有效的用例吗?
From the Java docs:
来自 Java 文档:
thenApply(Function<? super T,? extends U> fn)
Returns a new
CompletionStage
that, when this stage completes normally, is executed with this stage's result as the argument to the supplied function.
返回一个新的
CompletionStage
,当这个阶段正常完成时,将这个阶段的结果作为提供函数的参数执行。
thenCompose(Function<? super T,? extends CompletionStage<U>> fn)
Returns a new
CompletionStage
that, when this stage completes normally, is executed with this stage as the argument to the supplied function.
返回一个新的
CompletionStage
,当这个阶段正常完成时,将这个阶段作为提供函数的参数执行。
I get that the 2nd argument of thenCompose
extends the CompletionStage where thenApply
does not.
我知道第二个参数thenCompose
扩展了 CompletionStage 在哪里thenApply
没有。
Could someone provide an example in which case I have to use thenApply
and when thenCompose
?
有人可以提供一个示例,在哪种情况下我必须使用thenApply
以及何时使用thenCompose
?
采纳答案by Joe C
thenApply
is used if you have a synchronous mapping function.
thenApply
如果您有同步映射功能,则使用。
CompletableFuture<Integer> future =
CompletableFuture.supplyAsync(() -> 1)
.thenApply(x -> x+1);
thenCompose
is used if you have an asynchronous mapping function (i.e. one that returns a CompletableFuture
). It will then return a future with the result directly, rather than a nested future.
thenCompose
如果您有异步映射函数(即返回 a 的函数CompletableFuture
),则使用它。然后它将直接返回带有结果的未来,而不是嵌套的未来。
CompletableFuture<Integer> future =
CompletableFuture.supplyAsync(() -> 1)
.thenCompose(x -> CompletableFuture.supplyAsync(() -> x+1));
回答by Didier L
The updated Javadocs in Java 9 will probably help understand it better:
Java 9 中更新的 Javadocs 可能有助于更好地理解它:
thenApply
然后申请
<U> CompletionStage<U> thenApply?(Function<? super T,? extends U> fn)
<U> CompletionStage<U> thenApply?(Function<? super T,? extends U> fn)
Returns a new
CompletionStage
that, when this stage completes normally, is executed with this stage's result as the argument to the supplied function.This method is analogous to
Optional.map
andStream.map
.See the
CompletionStage
documentation for rules covering exceptional completion.
返回一个新的
CompletionStage
,当这个阶段正常完成时,将这个阶段的结果作为提供函数的参数执行。这种方法类似于
Optional.map
和Stream.map
。有关
CompletionStage
涵盖异常完成的规则,请参阅文档。
thenCompose
然后撰写
<U> CompletionStage<U> thenCompose?(Function<? super T,? extends CompletionStage<U>> fn)
Returns a new
CompletionStage
that is completed with the same value as theCompletionStage
returned by the given function.When this stage completes normally, the given function is invoked with this stage's result as the argument, returning another
CompletionStage
. When that stage completes normally, theCompletionStage
returned by this method is completed with the same value.To ensure progress, the supplied function must arrange eventual completion of its result.
This method is analogous to
Optional.flatMap
andStream.flatMap
.See the
CompletionStage
documentation for rules covering exceptional completion.
返回一个
CompletionStage
与CompletionStage
给定函数返回的值相同的新值。当此阶段正常完成时,将使用此阶段的结果作为参数调用给定函数,并返回另一个
CompletionStage
. 当该阶段正常完成时,CompletionStage
此方法返回的值以相同的值完成。为确保进度,提供的函数必须安排其结果的最终完成。
这种方法类似于
Optional.flatMap
和Stream.flatMap
。有关
CompletionStage
涵盖异常完成的规则,请参阅文档。
回答by Dorjee
I think the answered posted by @Joe C is misleading.
我认为@Joe C 发布的回答具有误导性。
Let me try to explain the difference between thenApply
and thenCompose
with an example.
让我试着解释之间的差别thenApply
,并thenCompose
用一个例子。
Let's suppose that we have 2 methods: getUserInfo(int userId)
and getUserRating(UserInfo userInfo)
:
假设我们有 2 个方法:getUserInfo(int userId)
和getUserRating(UserInfo userInfo)
:
public CompletableFuture<UserInfo> getUserInfo(userId)
public CompletableFuture<UserRating> getUserRating(UserInfo)
Both method return types are CompletableFuture
.
两种方法的返回类型都是CompletableFuture
.
We want to call getUserInfo()
first, and on its completion, call getUserRating()
with the resulting UserInfo
.
我们想先调用getUserInfo()
,并在调用完成时getUserRating()
使用结果调用UserInfo
。
On the completion of getUserInfo()
method, let's try both thenApply
and thenCompose
. The difference is in the return types:
在getUserInfo()
方法完成时,让我们同时尝试thenApply
和thenCompose
。区别在于返回类型:
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.
thenCompose()
就像Scala 的一样flatMap
,它可以将嵌套的期货展平。
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()
原样返回嵌套的期货,但将嵌套的期货展thenCompose()
平,CompletableFutures
以便更容易地将更多的方法调用链接到它。
回答by 1283822
thenApply
and thenCompose
are methods of CompletableFuture
. Use them when you intend to do something to CompleteableFuture
's result with a Function
.
thenApply
和thenCompose
是的方法CompletableFuture
。当你打算做些什么来使用他们CompleteableFuture
的一个结果Function
。
thenApply
and thenCompose
both return a CompletableFuture
as their own result. You can chain multiple thenApply
or thenCompose
together. Supply a Function
to each call, whose result will be the input to the next Function
.
thenApply
并且thenCompose
都返回 aCompletableFuture
作为他们自己的结果。您可以将多个链接thenApply
或链接thenCompose
在一起。Function
为每个调用提供 a ,其结果将是下一个 的输入Function
。
The Function
you supplied sometimes needs to do something synchronously. The return type of your Function
should be a non-Future
type. In this case you should use thenApply
.
在Function
你提供的,有时需要同步做一些事情。您的返回类型Function
应该是非Future
类型。在这种情况下,您应该使用thenApply
.
CompletableFuture.completedFuture(1)
.thenApply((x)->x+1) // adding one to the result synchronously, returns int
.thenApply((y)->System.println(y)); // value of y is 1 + 1 = 2
Other times you may want to do asynchronous processing in this Function
. In that case you should use thenCompose
. The return type of your Function
should be a CompletionStage
. The next Function
in the chain will get the result of that CompletionStage
as input, thus unwrapping the CompletionStage
.
其他时候你可能想在这个中做异步处理Function
。在这种情况下,您应该使用thenCompose
. 您的返回类型Function
应该是CompletionStage
. Function
链中的下一个将得到它的结果CompletionStage
作为输入,从而解开CompletionStage
.
// addOneAsync may be implemented by using another thread, or calling a remote method
abstract CompletableFuture<Integer> addOneAsync(int input);
CompletableFuture.completedFuture(1)
.thenCompose((x)->addOneAsync(x)) // doing something asynchronous, returns CompletableFuture<Integer>
.thenApply((y)->System.println(y)); // y is an Integer, the result of CompletableFuture<Integer> above
This is a similar idea to Javascript's Promise
. Promise.then
can accept a function that either returns a value or a Promise
of a value. The reason why these two methods have different names in Java is due to generic erasure. Function<? super T,? extends U> fn
and Function<? super T,? extends CompletionStage<U>> fn
are considered the same Runtime type - Function
. Thus thenApply
and thenCompose
have to be distinctly named, or Java compiler would complain about identical method signatures. The end result being, Javascript's Promise.then
is implemented in two parts - thenApply
and thenCompose
- in Java.
这与 Javascript 的Promise
. Promise.then
可以接受返回值或Promise
值的函数。这两种方法在 Java 中具有不同名称的原因是泛型擦除。Function<? super T,? extends U> fn
并且Function<? super T,? extends CompletionStage<U>> fn
被认为是相同的运行时类型 - Function
。因此thenApply
,thenCompose
必须明确命名,否则 Java 编译器会抱怨相同的方法签名。最终的结果是,Javascript 的Promise.then
实现分为两部分 -thenApply
和thenCompose
- 在 Java 中。
You can read my other answerif you are also confused about a related function thenApplyAsync
.
如果您也对相关功能感到困惑,可以阅读我的其他答案thenApplyAsync
。