首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从异步方法抛出异常是否合理?

从异步方法抛出异常是否合理?
EN

Stack Overflow用户
提问于 2019-01-16 16:46:29
回答 3查看 1.4K关注 0票数 5

在Java中开发一个具有CompletableFuture返回类型的异步方法,我们期望得到的CF能够正常或异常地完成,这取决于该方法是成功还是失败。

但是,考虑一下,例如,我的方法写入了一个AsynchronousChannel,并获得了一个打开该通道的异常。它甚至还没有开始写作。因此,在这种情况下,我只想让异常流到调用者。对吗?

尽管调用者必须处理两个失败场景:( 1)异常,或( 2)拒绝承诺。

或者,我的方法是否应该抓住这个例外,并返回一个被拒绝的承诺呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-01-19 15:00:45

海事组织,选项1)使API更难使用,因为通信错误有两种不同的路径:

  1. “同步”异常,其中该方法结束抛出的异常。
  2. “异步”异常,其中该方法返回一个CF,该CF由一个异常完成。请注意,避免这种情况是不可能的,因为总是会在异步路径启动后才发现错误(例如超时)。

程序员现在必须确保这两条路径都被正确处理,而不仅仅是一条。

还值得注意的是,C#和Javascript的行为总是通过返回的Task/Promise报告在async函数正文中抛出的异常,即使是在第一个await之前抛出的异常,也不要以异常结束async函数调用。

Kotlin的协同机制也是如此,即使在使用Unconfined调度程序时也是如此。

代码语言:javascript
复制
class SynchronousExceptionExamples {
    @Test
    fun example() {
        log.info("before launch")
        val job = GlobalScope.launch(Dispatchers.Unconfined) {
            log.info("before throw")
            throw Exception("an-error")
        }
        log.info("after launch")
        Thread.sleep(1000)
        assertTrue(job.isCancelled)
    }
}

将产生

代码语言:javascript
复制
6 [main] INFO SynchronousExceptionExamples - before launch
73 [main @coroutine#1] INFO SynchronousExceptionExamples - before throw
(...)
90 [main] INFO SynchronousExceptionExamples - after launch

注意,由于异常发生在main线程中,但是launch以正确的Job结尾。

票数 2
EN

Stack Overflow用户

发布于 2019-01-16 17:06:08

我认为两者都是有效的设计。Datastax实际上以第一种方法开始了他们的设计,在这种方法中,借用一个连接是阻塞的,然后切换到完全异步模型(guide/#3-0-4)。

作为datastax驱动程序的用户,我对修复非常满意,因为它将api更改为真正的非阻塞(在您的示例中,即使打开一个通道也有代价)。

但我不认为这里有对与错..。

票数 2
EN

Stack Overflow用户

发布于 2019-01-16 17:22:59

从呼叫者的角度来看,这并没有多大的区别。在这两种情况下,无论是从方法引发的异常还是在可完成的未来调用get(),都将显示异常的原因。

我可能会争辩说,由可完成的未来抛出的异常应该是异步计算中的异常,而不是无法启动该计算。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54221665

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档