java - 从返回 CompletableFuture 的异步方法的同步部分抛出异常

标签 java asynchronous exception completable-future

此问题特定于 Java 和 CompletableFuture

如果我有如下所示的异步方法,

CompletableFuture<String> get() {
    /* Step #1: Do some sync prep work */
    String s = doSomethingSync();

    /* Step #2: Do something async (returning CompletableFuture) */
    return doSomethingAsync(s);
}

如果步骤 #1 中的代码抛出异常,get() 的调用方将在获取其返回的 CompletableFuture 之前收到异常,而如果步骤 #2 中返回的 CompletableFuture 内的代码抛出异常,则调用方仅在与返回的 CompletableFuture 交互时才会收到异常。

这表明 get() 的调用者应该编写一些复杂的异常处理代码来处理这两种情况。

下面是另一个异步方法 invokeGet() 的示例,该方法调用 get() 并返回其返回的 String 的长度:

CompletableFutre<Integer> InvokeGet() {
    try {
        CompletableFuture future = get();
        return furure.handle((result, throwable) -> {
           if (throwable != null) {
               /* Handle exception thrown in step #2 in get(), e.g. rethrow */
           } else {
               return result.length();
           }
        });
    } catch (Exception e) {
        /* Handle exception thrown in step #1 in get() */
        /* Return some value or throw */
    }
}

我的问题是:

get() 是否写得不好,因为它要求调用者进行这种复杂的异常处理,还是这是一种常见的模式?返回 CompletableFuture 的异步方法是否应该将自己限制为在出现错误时返回错误的 future,以便其调用者不必编写此类错误处理代码?

最佳答案

简而言之,这取决于您自己的实现,但可以改进。如果您想通过不同的线程忽略、记录或响应异常(基本示例 here ),则让调用线程处理异常可能会很有帮助。然而,我见过的很多模式(在this posts answer中看到)会让您包含带有try-catch-blockasync函数,并重新抛出一个对您的应用程序更有用的异常,由父线程处理,我认为这更好一点。

如果您正在寻找不同的异常处理,请参阅此 article 以获取不同处理的示例。

关于java - 从返回 CompletableFuture 的异步方法的同步部分抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51883520/

相关文章:

java - MQ 队列与批处理 : how to replay asynchronous process when it fails

javascript - 异步等待无法正常工作

java - C++ 中的 scanf、memset 和几个 while 在 Java 中是什么意思?

java - 限制无限并行流

javascript - RequireJS - 在需求流和内联中加载 AMD 模块

scala - Scala 中 NonFatal 和 Exception 的区别

c++ - 无法从堆栈对象中捕获异常

java - "test">> : -c: line 0: unexpected EOF while looking for matching `"'

Collectors.groupingBy 的 Java 8 类型检查

c# - 使用 ContinueWith() 时如何获取原始异常?