问题
I was trying .exceptionally and .handle but those don't seem to work. In scala, you can call a method on the future with a closure that is just like a finally block(it runs on exception AND on success) AND it propogates the exception or success up the chain as-is.
I tried this...
CompletableFuture<Object> future = newFuture.handle((r, e) -> {
if(r != null)
return r;
else if(e != null)
return e;
else
return new RuntimeException("Asdf");
});
Assert.assertTrue(future.isCompletedExceptionally());
but that test fails as the future completely successfully with a result of exception(how weird).
回答1:
Use CompletableFuture#whenComplete(BiConsumer). Its javadoc states
Returns a new
CompletionStage
with the same result or exception as this stage, that executes the given action when this stage completes.When this stage is complete, the given action is invoked with the result (or
null
if none) and the exception (ornull
if none) of this stage as arguments. The returned stage is completed when the action returns. If the supplied action itself encounters an exception, then the returned stage exceptionally completes with this exception unless this stage also completed exceptionally.
In other words, it will be invoked regardless of success or failure and will propagate the initial future's state (unless the BiConsumer
throws an exception).
CompletableFuture<String> future2 = newFuture.whenComplete((r, e) -> {
// consume the result
});
If you needed to transform the result (in your example, you don't), then you could use handle
and propagate things yourself.
回答2:
ohhhhh, I think I got it....something like this seems to work
CompletableFuture<Integer> future2 = newFuture.handle((r, e) -> {
//put finally like logic right here....
if(r != null)
return r;
else if(e != null)
throw new RuntimeException(e);
else
throw new RuntimeException("weird");
});
来源:https://stackoverflow.com/questions/39187368/how-to-invoke-completablefuture-callback-while-propagating-result-or-error