gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:04:54 25 4
gpt4 key购买 nike

我正在阅读 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

因此传播了异常。有人可以提供一个有意义的例子,这到底意味着什么,以及使用 andThen 和我想从中恢复的抛出异常的代码是否安全。谢谢。

最佳答案

不要throw 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 之后执行副作用函数完成了。

当 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)

当 future 失败时也是如此。 andThen 之后的代码执行,但是 andThen 之后的代码的结果被忽略,最终结果是 Future 结果。

所以 andThen用于在 Future 完成后立即运行副作用代码。 andThen还将最终输出保持为 Future s输出。

是这样的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与前面的Future 一起完成结果(看上面addThen的实现)

在 finally block 内 p complete r表示新的 Future 是使用 p.future 创建的并使用以前的 future 结果完成,即 r

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

是的。您可以使用多个 andThen 链接多个回调调用,这些回调按照andThen的顺序依次执行电话。这与 onComplete 相比可以多次使用的方法来注册多个回调,但这些回调的顺序是不确定的。

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这是前一个 future 的结果被提供给pf (看上面的andThen代码)

关于java - Scala future 和 `andThen` 异常传播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40114873/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com