java-Scala Futures和`andThen`异常传播

我正在阅读scala.concurrent.Future模块中andThen函数Scala 2.11.8文档,其中显示以下内容

def andThen[U](pf: PartialFunction[Try[T], U])
              (implicit executor: ExecutionContext): Future[T]

Applies the side-effecting function to the result of this future, and
returns a new future with the result of this future.

This method allows one to enforce that the callbacks are executed in a
specified order.

Note that if one of the chained andThen callbacks throws an exception,
that exception is not propagated to the subsequent andThen callbacks.
Instead, the subsequent andThen callbacks are given the original value
of this future.

我不知道andThen不会传播异常,这也到底是什么意思,也没有提供示例.例如,如果我做这样的事情:

Future.successful { throw new RuntimeException("test") } andThen
                  { case _ => println("test") }

在Scala REPL中,我得到:

java.lang.RuntimeException: test
  ... 32 elided

因此,该异常得以传播.有人可以提供一个有意义的示例,它到底意味着什么,以及使用and是否安全,然后提供我想从中恢复的异常引发的代码.谢谢.

解决方法:

不要在Future.successful {}中引发异常.

这是正确的方法

Future { throw new RuntimeException("test") } andThen
                  { case _ => println("test") }

您可以使用以下代码行了解andThen的用法

Future.successful { 1 } andThen { case _ =>  "foo" }

替换

@ Future.successful { 1 } andThen { case _ =>  "foo" }
res7: Future[Int] = Success(1)

替换

@ Future.successful { 1 } andThen { case _ =>  println("foo") }
foo
res8: Future[Int] = Success(1)

替换

@ val result = Future.successful { 1 } andThen { case _ =>  "foo" }
result: Future[Int] = Success(1)

在上面的例子中

我们可以看到andthen之后执行了部分函数,​​但是忽略了部分函数返回类型.最后,结果输出是Future的结果,即Future [Int]

这意味着addThen用于在Future完成后立即执行副作用功能.

当未来是失败时

替换

@ val result = Future { throw new Exception("bar") } andThen { case _ =>  "foo" }
result: Future[nothing] = Failure(java.lang.Exception: bar)

替换

@ val result = Future { throw new Exception("bar") } andThen { case _ =>  println("foo") }
foo
result: Future[nothing] = Failure(java.lang.Exception: bar)

将来失败时也是如此. andThen之后的代码将被执行,而andThen之后的代码的结果将被忽略,最终结果为Future结果.

因此,Future完成后,andThen将用于运行副作用代码.然后将最终输出保留为期货输出.

这就是在标准库中实现andThen的方式.

然后位于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
  }

1) Applies the side-effecting function to the result of this future, and returns a new future with the result of this future.

pf是副作用代码,因为未使用其输出类型(无法使用). p.future是他正在谈论的新未来.
使用上一个Future结果完成Promise(请看上面addThen的实现)

在finally块p complete r内,意味着使用p.future创建了新的Future,并使用先前的r的未来结果完成了r

2) This method allows one to enforce that the callbacks are executed in a specified order.

是. pf在先前的将来完成之后执行.看一下在onComplete块内执行的代码pf.

3) Note that if one of the chained andThen callbacks throws an exception, that exception is not propagated to the subsequent andThen callbacks. Instead, the subsequent andThen callbacks are given the original value of this future.

r是前一个将来的结果,它被赋予pf(请看上面的andThen代码)

相关文章

共收录Twitter的14款开源软件,第1页Twitter的Emoji表情 Tw...
Java和Scala中关于==的区别Java:==比较两个变量本身的值,即...
本篇内容主要讲解“Scala怎么使用”,感兴趣的朋友不妨来看看...
这篇文章主要介绍“Scala是一种什么语言”,在日常操作中,相...
这篇文章主要介绍“Scala Trait怎么使用”,在日常操作中,相...
这篇文章主要介绍“Scala类型检查与模式匹配怎么使用”,在日...