问题描述
问题很简单:我正在寻找一种与 CompletableFuture#supplyAsync
一起使用 CompletableFuture#exceptionally
的优雅方法.这是行不通的:
The question is rather simple: I'm looking for an elegant way of using CompletableFuture#exceptionally
alongside with CompletableFuture#supplyAsync
. This is what does not work:
private void doesNotCompile() {
CompletableFuture<String> sad = CompletableFuture
.supplyAsync(() -> throwSomething())
.exceptionally(Throwable::getMessage);
}
private String throwSomething() throws Exception {
throw new Exception();
}
我认为 exceptionally()
背后的想法是为了处理抛出 Exception
的情况.但是,如果我这样做,它会起作用:
I thought the idea behind exceptionally()
was precisely to handle cases where an Exception
is thrown. Yet if I do this it works:
private void compiles() {
CompletableFuture<String> thisIsFine = CompletableFuture.supplyAsync(() -> {
try {
throwSomething();
return "";
} catch (Exception e) {
throw new RuntimeException(e);
}
}).exceptionally(Throwable::getMessage);
}
我可以解决这个问题,但是它看起来很可怕,而且很难维护.没有一种方法可以保持这种清洁状态,而无需将所有 Exception
都转换为 RuntimeException
吗?
I could work with that, but it looks horrible and makes things harder to maintain. Is there not a way to keep this clean which doesn't require transforming all the Exception
into RuntimeException
?
推荐答案
这可能不是一个超级流行的库,但是我们在内部使用它(有时我也在那里做一些工作;虽然次要): NoException .根据我的口味写的真的非常非常好.这不是唯一的东西,但肯定涵盖了您的用例:
This might not be a super popular library, but we use it (and from times to times I do some work there too; minor though) internally: NoException. It is really, really nicely written for my taste. This is not the only thing it has, but definitely covers your use case:
以下是示例:
import com.machinezoo.noexception.Exceptions;
import java.util.concurrent.CompletableFuture;
public class SO64937499 {
public static void main(String[] args) {
CompletableFuture<String> sad = CompletableFuture
.supplyAsync(Exceptions.sneak().supplier(SO64937499::throwSomething))
.exceptionally(Throwable::getMessage);
}
private static String throwSomething() throws Exception {
throw new Exception();
}
}
或者您可以自己创建它们:
Or you can create these on your own:
final class CheckedSupplier<T> implements Supplier<T> {
private final SupplierThatThrows<T> supplier;
CheckedSupplier(SupplierThatThrows<T> supplier) {
this.supplier = supplier;
}
@Override
public T get() {
try {
return supplier.get();
} catch (Throwable exception) {
throw new RuntimeException(exception);
}
}
}
@FunctionalInterface
interface SupplierThatThrows<T> {
T get() throws Throwable;
}
和用法:
CompletableFuture<String> sad = CompletableFuture
.supplyAsync(new CheckedSupplier<>(SO64937499::throwSomething))
.exceptionally(Throwable::getMessage);
这篇关于让CompletableFuture例外地()处理supplyAsync()异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!