理解这个和 Then 的例子

Make sense of this andThen example

这是来自 scaladoc 的 andThen 示例:

val f = Future { 5 }
f andThen {
  case r => sys.error("runtime exception")
} andThen {
  case Failure(t) => println(t)
  case Success(v) => println(v)
}

不管 Future 最终是什么,行 case r => sys.error("runtime exception") 都不会抛出异常吗?对我来说真的没有任何意义,但也许我错过了一些东西。

是的,无论 Future 最终是什么,它都会抛出异常。

抛出异常可以作为抛出异常的线程的消息。

一般来说,

andThen 用于在给定的 future 完成后执行一些副作用代码,andThen 之后的操作结果类型与原始 future 的结果相同。因此,您可以进行模式匹配并期待与原始未来相同的结果。

在你的例子中,副作用操作是抛出异常,但它可以是任何其他有用的副作用操作,如写入文件、关闭资源等

这是标准 Scala 库中 andThen 的实现。

andThen 用于 运行 一些副作用操作,一旦调用它的 future 完成,但需要注意的是整个操作的结果类型将是 future具有原始的未来结果。

 def andThen[U](pf: PartialFunction[Try[T], U])(implicit executor: ExecutionContext): Future[T] = {
    val p = Promise[T]()
    onComplete {
      case r => try pf.applyOrElse[Try[T], Any](r, Predef.conforms[Try[T]]) finally p complete r
    }
    p.future
  }

andThen操作future返回原始future结果后的通知。

正如@Yuval Itzchakov 所说,您可以使用它来将异常抛出到主线程。但一般用于future完成后的side effecting。

Doesn't the line case r => sys.error("runtime exception") throw an exception no matter what the Future ends up to be?

是的,确实如此。但是你需要记住一件事,在 Future 中抛出的异常不会自动在主执行线程上重新抛出,它们需要被处理并从主线程重新抛出以使程序终止。

所有 andThen 允许您做的就是按顺序执行一些副作用方法,然后继续期货的组合。有很多事情可能需要注意副作用,例如处理开放资源。如果你只想编写期货,我会用 Future.map 代替。