传递给ComppletableFuture.exceptionally()的异常处理程序是否必须返回有意义的值?
我习惯了ListenableFuture
模式,带有和回调,例如onSuccess()
onFailure()
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
ListenableFuture<String> future = service.submit(...)
Futures.addCallback(future, new FutureCallback<String>() {
public void onSuccess(String result) {
handleResult(result);
}
public void onFailure(Throwable t) {
log.error("Unexpected error", t);
}
})
似乎Java 8的ComppletableFuture
旨在处理或多或少相同的用例。天真地,我可以开始将上面的例子翻译为:
CompletableFuture<String> future = CompletableFuture<String>.supplyAsync(...)
.thenAccept(this::handleResult)
.exceptionally((t) -> log.error("Unexpected error", t));
这当然没有版本那么冗长,看起来非常有前途。ListenableFuture
但是,它不会编译,因为不采用 ,它需要一个 -- 在本例中为 .exceptionally()
Consumer<Throwable>
Function<Throwable, ? extends T>
Function<Throwable, ? extends String>
这意味着我不能只记录错误,我必须想出一个值在错误情况下返回,并且在错误情况下没有有意义的值要返回。我可以返回,只是为了获取要编译的代码:String
String
null
.exceptionally((t) -> {
log.error("Unexpected error", t);
return null; // hope this is ignored
});
但是这又开始变得冗长了,除了冗长之外,我不喜欢让它漂浮在周围 - 这表明有人可能会试图检索或捕获该值,并且在某个时候我可能会遇到意想不到的事情 。null
NullPointerException
如果拿了一个,我至少可以做这样的事情——exceptionally()
Function<Throwable, Supplier<T>>
.exceptionally((t) -> {
log.error("Unexpected error", t);
return () -> {
throw new IllegalStateException("why are you invoking this?");
}
});
--但事实并非如此。
当永远不应该产生有效值时,正确的做法是什么?在新的 Java 8 库中,我还可以做一些其他事情来更好地支持这个用例吗?exceptionally()
CompletableFuture