让我们举一个例子:
我们有四种方法:
CompletableFututre<Void> loadAndApply(SomeObject someObject);
CompletableFuture<SomeData> loadData();
A processA(SomeData data);
B processB(SomeData data);
loadAndApply
结合了所有其他方法。 loadData
长时间获取数据。然后,将someObject.A
设置为运行processA(data)
的结果,并将someObject.B
设置为运行processB(data)
的结果我们不能同时应用
processA
和processB
,因为processA
只能在swingExecutor
上运行,而processB
只能在backgroundExecutor
上运行。所以我的问题是:我们可以以某种美观的方式将所有这些方法链接起来吗?
目前,我像这样启动它们:
CompletableFututre<Void> loadAndApply(SomeObject someObject) {
return loadData()
.thenApplyAsync(data -> { someObject.setA(processA(data)); return data; }, swingExecutor)
.thenAcceptAsync(data -> someObject.setB(processB(data)), backgroundExecutor);
}
有什么方法看起来比
applyAsync
更好,实际上没有对给定对象应用任何内容,只是在下一个将来返回它? 最佳答案
您可以通过将CompletionStage.thenCompose(Function)
与CompletableFuture.allOf(CompletableFuture...)
结合使用来实现。 Function
使用的thenCompose
的通用签名为:Function<? super T, ? extends CompletionStage<U>>
。
public CompletableFuture<Void> loadAndApply(SomeObject object) {
return loadData().thenCompose(data ->
CompletableFuture.allOf(
CompletableFuture.runAsync(() -> object.setA(processA(data)), swingExecutor),
CompletableFuture.runAsync(() -> object.setB(processB(data)), backgroundExecutor)
) // End of "allOf"
); // End of "thenCompose"
} // End of "loadAndApply"
这有一个额外的好处。在当前使用
thenAcceptAsync
阶段的代码中,必须等待thenApplyAsync
阶段完成才能执行。当使用以上代码时,setA
和setB
都将在各自的执行程序中同时运行。为了方便起见,以下是
allOf
的Javadoc:返回一个新的CompletableFuture,当所有
给定CompletableFutures完成。如果给定的任何
CompletableFutures异常完成,然后返回
CompletableFuture也这样做,持有CompletionException
此异常是其原因。否则,如果有的话,
给定的CompletableFutures不反映在返回的值中
CompletableFuture,但可以通过检查它们来获得
个别地。如果未提供CompletableFutures,则返回
CompletableFuture已完成,值为null。
该方法的应用之一是等待一组完成
在继续执行程序之前,先确定独立的CompletableFutures,如:
CompletableFuture.allOf(c1,c2,c3).join();。
...以及
thenCompose
的Javadoc:返回一个新的CompletionStage,其值与
给定函数返回的CompletionStage。
当此阶段正常完成时,将使用
这个阶段的结果作为参数,返回另一个
CompletionStage。该阶段正常完成后,
此方法返回的CompletionStage用相同的方法完成
值。
为了确保进度,提供的功能必须安排最终的
完成其结果。
此方法类似于Optional.flatMap和Stream.flatMap。
有关涵盖特殊情况的规则,请参见CompletionStage文档。
完成。
注意:实现
CompletableFuture
的CompletionStage
会覆盖thenCompose
,但会使返回类型更具体(返回CompletableFuture
而不是CompletionStage
)。