【问题标题】:Throwing exception from a scala.concurrent.Future从 scala.concurrent.Future 抛出异常
【发布时间】:2016-02-01 09:35:18
【问题描述】:

我试图使用scala.concurrent.Future 重现此问题How do I get hold of exceptions thrown in a Scala Future?,我期待异常被吞下,但它似乎没有发生。有什么解释吗?

import scala.concurrent._
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global

def runWithTimeout[T](timeoutMs: Long)(f: => Future[T]) : T = {
  Await.result(f, timeoutMs.millis)
}

runWithTimeout(50) { Future { "result" } }

runWithTimeout(50) { Future { throw new Exception("deliberate") } }

【问题讨论】:

    标签: scala future


    【解决方案1】:

    Futures 不会吞下异常(至少不是通常意义上的,即“捕获并丢弃”)。当你在未来抛出异常时(无论是在map/flatMap 的主体中还是在使用Future.apply 时),该异常确实不会传播到当前线程中,但它会在将来保留并成为未来的结果。实际上,未来的最终结果是Try[T],因此它将以TSuccess[T])类型的正确结果完成,ThrowableFailure[T])完成)。

    另一个关键点是,当您调用Await.result 时,您基本上要求通过等待未来的最终结果来阻塞当前线程,无论是正确的结果还是异常。如果发生异常,它将在调用Await.result 的位置重新抛出。 如果您不希望重新抛出异常,则可以改用Await.ready。它将等待未来的完成并返回未来本身,无论它是正常完成还是通过异常完成。然后你可以通过Future.value检索未来的结果

    【讨论】:

    • 啊!这太好了!感谢您非常清楚的解释
    猜你喜欢
    • 2015-09-25
    • 2013-05-24
    • 2011-07-17
    • 2017-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-30
    相关资源
    最近更新 更多