Reputation: 296
I have a future that would ideally take two parameters coming from two other futures. For this I have .thenCombine(), the trick here is that the second future needs the result of the first one.
Let's say:
I would like to have something like:
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));
Of course thenCombine() is not what I'm looking for and the code above looks dumb because I shouldn't need the customer afterwards, but this is only an example.
Is there a way to achieve this?
Upvotes: 2
Views: 3684
Reputation: 20618
Your solution is correct, the only issue is in the declaration of shopFuture
. You should use thenApply[Async]()
so that it can access the result of the first one:
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));
Note that the execution order remains sequential since shopFuture
requires the result of customerFuture
, and routeFuture
requires the result of shopFuture
. However if you have additional work to do with the Customer
or the Shop
, you could use additional thenApply[Async]
calls to run them.
If you don't have anything to do with those results, you might want to group all the 3 calls into a single supplyAsync()
:
CompletableFuture<Route> customerFuture = CompletableFuture.supplyAsync(() -> {
Customer customer = findCustomer(123));
Shop shop = getAllAccessibleShops(customer));
return findRoute(customer, shop)
});
See also CompletableFuture, supplyAsync() and thenApply() for the difference in behaviour between the two.
Upvotes: 3