微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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代码)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐