在Java中开发一个具有CompletableFuture返回类型的异步方法,我们期望得到的CF能够正常或异常地完成,这取决于该方法是成功还是失败。
但是,考虑一下,例如,我的方法写入了一个AsynchronousChannel,并获得了一个打开该通道的异常。它甚至还没有开始写作。因此,在这种情况下,我只想让异常流到调用者。对吗?
尽管调用者必须处理两个失败场景:( 1)异常,或( 2)拒绝承诺。
或者,我的方法是否应该抓住这个例外,并返回一个被拒绝的承诺呢?
发布于 2019-01-19 15:00:45
海事组织,选项1)使API更难使用,因为通信错误有两种不同的路径:
程序员现在必须确保这两条路径都被正确处理,而不仅仅是一条。
还值得注意的是,C#和Javascript的行为总是通过返回的Task/Promise报告在async函数正文中抛出的异常,即使是在第一个await之前抛出的异常,也不要以异常结束async函数调用。
Kotlin的协同机制也是如此,即使在使用Unconfined调度程序时也是如此。
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)
}
}将产生
6 [main] INFO SynchronousExceptionExamples - before launch
73 [main @coroutine#1] INFO SynchronousExceptionExamples - before throw
(...)
90 [main] INFO SynchronousExceptionExamples - after launch注意,由于异常发生在main线程中,但是launch以正确的Job结尾。
发布于 2019-01-16 17:06:08
我认为两者都是有效的设计。Datastax实际上以第一种方法开始了他们的设计,在这种方法中,借用一个连接是阻塞的,然后切换到完全异步模型(guide/#3-0-4)。
作为datastax驱动程序的用户,我对修复非常满意,因为它将api更改为真正的非阻塞(在您的示例中,即使打开一个通道也有代价)。
但我不认为这里有对与错..。
发布于 2019-01-16 17:22:59
从呼叫者的角度来看,这并没有多大的区别。在这两种情况下,无论是从方法引发的异常还是在可完成的未来调用get(),都将显示异常的原因。
我可能会争辩说,由可完成的未来抛出的异常应该是异步计算中的异常,而不是无法启动该计算。
https://stackoverflow.com/questions/54221665
复制相似问题