让CompletableFuture例外地

让CompletableFuture例外地

本文介绍了让CompletableFuture例外地()处理supplyAsync()异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题很简单:我正在寻找一种与 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()异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-22 20:31