I have 3 functions that return CompletionStage
. Let's say that they looks like:
CompletionStage<A> funcA();
CompletionStage<B> funcB();
CompletionStage<C> funcC(A a, B b);
Now I would like to write fuction funcD
that returns CompletionStage<C>
. Result is computed by funcC
and params cames from both funcA
and funcB
. Now the question is how to do it properly?
My attempts after reading documentation looks like this, but I'm not sure if it is proper usage. The problem is that after thenCombineAsync
I receive CompletionStage<CompletionStage<C>>
and the last line looks like ugly workaround to extract proper result. Can it be accomplished any better?
CompletionStage<C> funcD() {
CompletionStage<B> completionStageB = funcB();
return funcA()
.thenCombineAsync(completionStageB, (a,b) -> funcC(a,b))
.thenComposeAsync(result -> result);
}
Let's assume that method's declarations cannot be changed.
There's very simple rule for chaining here: The methods which return CompletionStage<Void> or CompletableFuture<Void> can only be chained with a method which takes a Runnable . The methods which return CompletionStage<U> can be chained with methods which takes Consumer<U> or Function<U,R> .
Returns a new CompletableFuture that is asynchronously completed by a task running in the given executor with the value obtained by calling the given Supplier. Returns a new CompletionStage that, when this stage completes normally, is executed with this stage's result as the argument to the supplied action.
completedFuture() is a static method of the CompletableFuture class and is used to get a new CompletableFuture that is in the completed stage, with the passed value as the result of the future.
The stage of completion is an indicator of progress and determines for an operation, work package, or project the ratio of the delivered output to the planned total output. As a percentage, it expresses the proportion of work performed that is part of an agreed total output.
There is no thenComposeWithBoth
. If you cannot modify method signatures, I would just leave it as is (but remove Async
-- see below). The only way to make this shorter is to join()
inside the Combine
stage:
funcA()
.thenCombineAsync(completionStageB, (a,b) -> funcC(a,b).join());
On a separate note, you are using ...Async
methods needlessly. Since your funcC
returns a CompletableFuture
, it is probably not long-running and there is no need to schedule it asynchronously. And result -> result
certainly does not need to run in a separate thread.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With