如何让未来依赖于Java中的另外两个

时间:2016-11-29 10:06:41

标签: java completable-future

我有一个未来理想情况下会从两个其他期货中获取两个参数。为此,我有.thenCombine(),这里的诀窍是第二个未来需要第一个结果。

让我们说:

  • 我有期货A,B和C
  • 未来B需要未来的结果A
  • 未来C需要未来A和B的结果

我希望有类似的东西:

CompletableFuture<Customer> customerFuture = CompletableFuture.supplyAsync(() -> findCustomer(123));
CompletableFuture<Shop> shopFuture         = CompletableFuture.supplyAsync((customer) ->getAllAccessibleShops(customer));
CompletableFuture<Route> routeFuture       = customerFuture.thenCombine(shopFuture, (cust, shop) -> findRoute(cust, shop));

当然,然后结合()并不是我想要的,上面的代码看起来很愚蠢,因为之后我不需要客户,但这只是一个例子。

有没有办法实现这个目标?

1 个答案:

答案 0 :(得分:2)

您的解决方案是正确的,唯一的问题是shopFuture的声明。您应该使用thenApply[Async](),以便它可以访问第一个结果:

CompletableFuture<Customer> customerFuture = CompletableFuture.supplyAsync(() -> findCustomer(123));
CompletableFuture<Shop> shopFuture         = customerFuture.thenApply((customer) -> getAllAccessibleShops(customer));
CompletableFuture<Route> routeFuture       = customerFuture.thenCombine(shopFuture, (cust, shop) -> findRoute(cust, shop));

请注意,执行顺序保持顺序,因为shopFuture需要customerFuture的结果,而routeFuture需要shopFuture的结果。但是,如果您还有其他与CustomerShop相关的工作,则可以使用其他thenApply[Async]来调用它们。

如果您对这些结果没有任何帮助,您可能希望将所有3个电话分组到一个supplyAsync()中:

CompletableFuture<Route> customerFuture = CompletableFuture.supplyAsync(() -> {
   Customer customer = findCustomer(123));
   Shop shop = getAllAccessibleShops(customer));
   return findRoute(customer, shop)
});

另见CompletableFuture, supplyAsync() and thenApply()两者之间的行为差​​异。