【问题标题】:Exception Passing Through scala.concurrent.Future?通过 scala.concurrent.Future 传递异常?
【发布时间】:2015-09-25 10:16:20
【问题描述】:

是否有可能抛出异常,转义Future 上下文?

因为 Future 一被定义就“评估”:

Future 的定义是否可以通过 Future 上下文引发异常?

scala> Future { Thread.sleep(3000); println("3 seconds elapsed"); 100 }
res2: scala.concurrent.Future[Int] = 
     scala.concurrent.impl.Promise$DefaultPromise@56113384

scala> 3 seconds elapsed

我想不出这样的例子。

scala> Future { throw new Exception("Foo!") }
res3: scala.concurrent.Future[Nothing] = 
  scala.concurrent.impl.Promise$DefaultPromise@47a86fbb

【问题讨论】:

    标签: scala exception future


    【解决方案1】:

    是的,但可能与您想的不太一样。根据source,只有不是 NonFatal 的错误才会转义Future.apply

     try Success(body) catch { case NonFatal(e) => Failure(e) }
    

    即诸如:VirtualMachineErrorOutOfMemoryErrorStackOverflowErrorThreadDeathLinkageErrorInterruptedExceptionControlThrowable.. 之类的异常将不会被捕获,因为它们代表您将无法处理的致命 JVM 错误.

    【讨论】:

    • StackOverflowError 由于某种原因实际上被认为是非致命的
    • Scaladocs 另有说法:scala-lang.org/api/current/#scala.util.control.NonFatal$ 也许他们不正确?
    • 我按照@dwickern 所说的运行了这个 REPL:scala> try { throw new StackOverflowError("...") } catch { case NonFatal(e) => "caught it" } java.lang.StackOverflowError: ... at .liftedTree1$1(<console>:12) ... 33 elided
    • 嗯。显然,他们在 2.10 和 2.11 之间的某个时间将 StackOverflowError 更改为致命:github.com/scala/scala/commit/…
    【解决方案2】:

    future 本身除了定义计算之外什么都不做。碰巧您正在使用默认情况下立即开始运行计算的构造函数(或应用方法)之一。不幸的是,异常处理和并发的混合是 scala.concurrent.Future 不明确的问题之一。更好的选择可能是使用scalaz.concurrent.Task,它将错误处理与显式并发相结合。

    【讨论】:

      【解决方案3】:

      你为什么要从你的未来抛出一个错误?

      Future 是一个 monad,它将在您处理它时处理延迟和异常。

      如果你看一下 Future 的实现,它看起来如下所示,

      trait Future[T] {    def onComplete(callback: Try[T] => Unit)(implicit exe..) }
      

      所以当你的 future 完成并且值可用时,你的回调方法将被调用并返回单元。

      如果你看到回调方法,你会知道你的结果是成功还是错误,Try[T] 会为你管理所有事情。

      【讨论】:

      • 我不想从 Future 抛出异常。我想知道这是否可能。
      猜你喜欢
      • 1970-01-01
      • 2011-01-30
      • 1970-01-01
      • 2018-08-29
      • 2010-09-08
      • 1970-01-01
      • 1970-01-01
      • 2021-06-02
      • 2021-01-16
      相关资源
      最近更新 更多