7

I have 3 different methods in my application. All are returning CompletableFuture<SomeType>. I want to execute method 1 and 2 in parallel. On completion of method 1 and 2, I want to trigger method 3 with parameters from method 1 and 2 return values.

Code example :

CompletableFuture<Request> future1 = RequestConverter.Convert(requestDto);
CompletableFuture<String> future2 = tokenProvider.getAuthToken();

CompletableFuture<CompletableFuture<String>> future3 = 
future1.thenCombine(future2,(request,token) -> 
requestProcessor.Process(request,token)); 

But the problem with the above code is that I am getting a CompletableFuture of CompletableFuture. I want to avoid this and get a simple CompletableFuture<String> without blocking. Is this possible?

Didier L
  • 18,905
  • 10
  • 61
  • 103
VinothNair
  • 614
  • 1
  • 7
  • 24
  • What about ```thenCompose```? – zhh Jan 09 '18 at 10:33
  • My understanding is "thenCompose" can be used only if we need result from only one CompletableFuture. But in this case i need result of both the CompletableFuture to trigger my third method. – VinothNair Jan 09 '18 at 12:42
  • I am getting a compile time exception if i use thenCompose. I am new to Java, so maybe i am missing some syntax. Can you please post the future3 syntax with your suggestion. – VinothNair Jan 09 '18 at 13:22
  • First use combine then compose, I will post my code soon. – zhh Jan 09 '18 at 13:27
  • I will try as per your suggestion. Please post your code as well, so that i can cross check whether my code is inline. Thanks – VinothNair Jan 09 '18 at 13:29
  • Note that java standards recommend that method and variable names start with a lowercase letter while class names start with an uppercase one. The syntax highlighting gets a bit messed up here since this convention is not followed. – Didier L Jan 09 '18 at 23:40

2 Answers2

6

As there is no method that combines thenCombine() and thenCompose(), you can use thenCompose() to unwrap nested CompletableFutures coming from your thenCombine():

CompletableFuture<CompletableFuture<String>> future3 = 
    future1.thenCombine(future2, (request,token) -> 
        requestProcessor.Process(request,token));

CompletableFuture<String> future4 = future3.thenCompose(c -> c);
Didier L
  • 18,905
  • 10
  • 61
  • 103
4

Suppose you have the Pair class.

class Pair<L, R> {
    public final L left;
    public final R right;

    public Pair(L left, R right) {
        this.left = left;
        this.right = right;
    }
}

Then you can first combine to a pair then compose.

CompletableFuture<Request> future1 = RequestConverter.Convert(requestDto);
CompletableFuture<String> future2 = tokenProvider.getAuthToken();

CompletableFuture<String> future3 = future1
    .thenCombine(future2, Pair::new)
    .thenCompose(pair -> requestProcessor.Process(pair.left, pair.right));
zhh
  • 2,346
  • 1
  • 11
  • 22