Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a .thenCompose() for CompletableFuture that also executes exceptionally?

I want to execute a CompletableFuture once another CompletableFuture finishes, regardless of whether or not the first one completes exceptionally (.thenCompose() only runs when execution completes normally).

For example:

CompletableFuture.supplyAsync(() -> 1L)
    .whenComplete((v, e) -> CompletableFuture.runAsync(() -> { 
        try {
            Thread.sleep(1000);
            System.out.println("HERE");
        } catch(InterruptedException exc) {
            return;
        }
    }))
    .whenComplete((v, e) -> System.out.println("ALL DONE"));

This prints

ALL DONE
HERE

and I would like it to be

HERE
ALL DONE

preferably without nesting the second whenComplete() inside the first.

Note that I don't care about the returned result/exception here.

like image 688
bcoughlan Avatar asked Dec 20 '14 03:12

bcoughlan


People also ask

What is completablefuture completeexceptionally() in Java?

What is CompletableFuture.completeExceptionally () in Java? completeExceptionally () is an instance method of the CompletableFuture which is used to complete the future with the given exception. The subsequent calls to methods where we can retrieve results like get () and join () throwing the given exception.

What are thenapply and thencompose methods of completablefuture?

thenApply and thenCompose are methods of CompletableFuture. Use them when you intend to do something to CompletableFuture 's result with a Function. thenApply and thenCompose both return a CompletableFuture as their own result.

What is thencompose in completablefuture<integer>?

CompletableFuture<Integer> future = CompletableFuture.supplyAsync ( () -> 1) .thenApply (x -> x+1); thenCompose is used if you have an asynchronous mapping function (i.e. one that returns a CompletableFuture ).

How do I get the result of a completablefuture?

The futureResult is returned without waiting for the long process to complete. Callers who want to get the result of this CompletableFuture can call futureResult.get (). Notice the complete () and completeExceptionally () methods: Both methods help manually complete a Future.


1 Answers

The trick is to use .handle((r, e) -> r) to suppress the error:

CompletableFuture.runAsync(() -> { throw new RuntimeException(); })
    //Suppress error
    .handle((r, e) -> r)
    .thenCompose((r) -> 
         CompletableFuture.runAsync(() -> System.out.println("HELLO")));
like image 171
bcoughlan Avatar answered Oct 06 '22 00:10

bcoughlan