在另一个CompletableFuture的结果上应用多个CompletableFuture的最佳方法是什么?

时间:2018-07-13 11:40:19

标签: java completable-future

让我们举一个例子: 我们有四种方法:

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)的结果 我们不能同时应用processAprocessB,因为processA只能在swingExecutor上运行,而processB只能在{{ 1}}。

所以我的问题是:我们可以以某种美观的方式将所有这些方法链接起来吗?

目前,我像这样启动它们:

backgroundExecutor

有没有比CompletableFututre<Void> loadAndApply(SomeObject someObject) { return loadData() .thenApplyAsync(data -> { someObject.setA(processA(data)); return data; }, swingExecutor) .thenAcceptAsync(data -> someObject.setB(processB(data)), backgroundExecutor); } 更好的方法,实际上对给定对象不应用任何东西,只是在下一个将来返回它?

1 个答案:

答案 0 :(得分:2)

您可以将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阶段完成才能执行。使用上述方法时,setAsetB都将在各自的执行程序中同时运行。

为方便起见,这是allOf的Javadoc:

  

返回一个新的CompletableFuture,当所有   给定CompletableFutures完成。如果给定的任何   CompletableFutures异常完成,然后返回   CompletableFuture也这样做,持有CompletionException   此异常是其原因。否则,如果有的话,   给定的CompletableFutures不反映在返回的值中   CompletableFuture,但可以通过检查它们来获得   个别地。如果未提供CompletableFutures,则返回   CompletableFuture完成,值为空。

     

此方法的应用是等待一组完成   在继续执行程序之前,先确定独立的CompletableFutures,如:   CompletableFuture.allOf(c1,c2,c3).join();。

...以及thenCompose的Javadoc:

  

返回一个新的CompletionStage,其值与   给定函数返回的CompletionStage。

     

此阶段正常完成时,将使用   这个阶段的结果作为参数,返回另一个   CompletionStage。当该阶段正常完成时,   此方法返回的CompletionStage用相同的方法完成   值。

     

为确保进度,提供的功能必须最终安排   完成结果。

     

此方法类似于Optional.flatMap和Stream.flatMap。

     

有关涵盖特殊情况的规则,请参见CompletionStage文档   完成。

注意:实现CompletableFuture的{​​{1}}覆盖CompletionStage,但使返回类型更具体(返回thenCompose而不是CompletableFuture