异常通过 scala.concurrent.Future?

Exception Passing Through scala.concurrent.Future?

是否可能抛出异常,逃离 Future 上下文?

因为 Future "evaluates" 一旦定义:

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

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

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

即像这样的异常:VirtualMachineErrorOutOfMemoryErrorWhosebugErrorThreadDeathLinkageErrorInterruptedExceptionControlThrowable.. 将不会被捕获为它们表示您将无法处理的致命 JVM 错误。

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

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

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

如果您查看 Future 实现,它看起来如下所示,

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

因此,当您的未来完成并且值可用时,您的回调方法将被调用并且 return 单元。

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