如何控制CompletableFuture的流程?

问题描述 投票:1回答:1

请考虑以下代码:

final CompletableFuture<Object> future = giveMeFuture();

future.thenAcceptAsync(o -> {
    throw new RuntimeException("Some random exception happened.");
}).exceptionally(throwable -> {
    System.out.println("EXCEPTION 1: " + throwable.getLocalizedMessage());
    return null;
});
future.exceptionally(throwable -> {
    System.out.println("EXCEPTION 2: " + throwable.getLocalizedMessage());
    return null;
});

我注意到以下行为:

  • 当未来正常完成时,只打印EXCEPTION 1。这是预期的,因为我们在thenAcceptAsync中抛出异常。
  • 当未来完成异常时,EXCEPTION 1EXCEPTION 2都会打印出来。

我只想在执行EXCEPTION 1时发生异常时打印thenAcceptAsync。所以在第二种情况下,当未来特别完成时,我只想要打印EXCEPTION 2

我怎么能用CompletableFuture做到这一点?我知道我可以在try / catch中添加一个好的老thenAcceptAsync,但我想知道这是否可以单独使用CompletableFuture功能。

更新

以下流程不起作用:

future
    .exceptionally(throwable -> {
        System.out.println("EXCEPTION 2: " +throwable.getLocalizedMessage());
        return null;
    })
    .thenAcceptAsync(o -> {
        throw new RuntimeException("Some random exception happened.");
    })
    .exceptionally(throwable -> {
        System.out.println("EXCEPTION 1: " + throwable.getLocalizedMessage());
        return null;
    });

如果我们输入EXCEPTION 2流量,我们返回null。现在用thenAcceptAsync论证调用null。我们可以在参数null上添加一个o检查,但我认为这不是一个好主意。我们正在唤醒执行程序线程,发现参数onull

    .thenAcceptAsync(o -> {
        if (o != null) {
            // do something with the parameter
            throw new RuntimeException("Some random exception happened.");
        }
    })
java completable-future
1个回答
1
投票

怎么样:

    future
        .handleAsync((object, throwable) -> {
            if (throwable !=null) {
                    System.out.println("EXCEPTION from future completion: " + throwable.getClass().getName());
                return null;
            }
            else {
                throw new IllegalStateException("async processing failed");
            }
        })
        .exceptionally(throwable -> {
                System.out.println("EXCEPTION from completion stage: " + throwable.getClass().getName());
            return null;
        });

或将您的代码更改为:

    future
        .exceptionally(throwable -> {
            System.out.println("EXCEPTION 2: " +throwable.getLocalizedMessage());
            return null;
        })
        .thenAcceptAsync(o -> {
            throw new RuntimeException("Some random exception happened.");
        })
        .exceptionally(throwable -> {
            System.out.println("EXCEPTION 1: " + throwable.getLocalizedMessage());
            return null;
        });

每次将操作链接到将来时,它都会与其他“链接”分开执行。您正在制作两个操作链,一个使用future.thenAcceptAsync,另一个使用future.exceptionally,这些操作链彼此分开执行。

© www.soinside.com 2019 - 2024. All rights reserved.