问题
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.
回答1:
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")));
回答2:
Maybe you should use whenCompleteAsync instead of CompletableFuture.runAsync:
CompletableFuture<Long> cf = CompletableFuture.supplyAsync(() -> 1L)
.whenCompleteAsync((v, e) -> {
try {
Thread.sleep(1000);
System.out.println("HERE");
} catch(InterruptedException exc) {
//nothing
}
//check that thowing an exception also executes the next cf
throw new RuntimeException("exception");
})
.whenCompleteAsync((v, e) -> System.out.println("ALL DONE (exception thrown: " + e + ")"));
System.out.println("CF code finished");
System.out.println(cf.get());
来源:https://stackoverflow.com/questions/27576569/is-there-a-thencompose-for-completablefuture-that-also-executes-exceptionally