为什么 Future 的 andThen 不链接结果?
Why does the andThen of Future not chain the result?
这个andThen
的意思我从这个answer中学到的是一个函数composer。
说
f andThen g andThen h
将等于
h(g(f(x)))
这意味着 h function
将接收来自 g(f(x))
的输入
但是对于Future
中的andThen
,后面的andThen的所有闭包总是从原来的Future
接收结果。
Future{
1
}.andThen{ case Success(x) =>
println(x) // print 1
Thread.sleep(2000)
x * 2
}.andThen{ case Success(x) =>
println(x) // print 1
Thread.sleep(2000)
x * 2
}
比较
val func: Function1[Int, Int] = { x: Int =>
x
}.andThen { y =>
println(y) // print 1
y * 2
}.andThen { z =>
println(z) // print 2
z * 2
}
func(1)
让 Future::andThen(s) 从原始 Future 接收所有相同结果而不是链接 Future 的原因是什么?我观察到这些链式andThen会顺序执行,所以可能不是为了并行目的。
scala.concurrent.Future
是两种异步方法的折衷方案:
Applies the side-effecting function to the result of this future, and
returns a new future with the result of this future.
所以 andThen
很可能来自 OOP 领域。要获得与 Function1.andThen
类似的结果,您可以使用 map
方法:
Future(1).map {_ * 2}.map {_ * 2}
andThen
与 onComplete
有一点不同:andThen
的结果 Future 仍然 return 相同的结果,但会等到提供的观察者 return 或扔东西。这就是为什么在文档中写道:
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.
所以它对新 Future
的结果完全没有任何作用。甚至不能用它自己的例外来破坏它。 andThen
和 onComplete
只是观察者的顺序和并行绑定。
让我总结一下这个精彩的讨论。
比如说,我们有 tf: Future[T] =...
,还有两个函数,f: T => U
和 g: U => V
我们可以做到vf: Future[V] = tf map f map g
,和vf: Future[V] = tf map (f andThen g)
一样
在另一个用例中,有 fp: PartialFunction[T, U]
和 gp: PartialFunction[U, V]
,
我们可以 运行 tf1: Future[T] = tf andThen fp andThen gp
- 这些部分函数将根据 tf 产生的值调用,没有外部影响 - 只会产生副作用。此序列在调用 gp
.
之前等待 fp
还有一个 future 操作,onComplete,是这样工作的:有 f: Try[T] => U
,即使 future 以错误结束,调用 tf onComplete f
也会调用 f
; tf onComplete f
的结果是 Unit
.
类型
此外,如果您的函数 f
生成 Future
,您将需要使用 flatMap
.
这个andThen
的意思我从这个answer中学到的是一个函数composer。
说
f andThen g andThen h
将等于
h(g(f(x)))
这意味着 h function
将接收来自 g(f(x))
但是对于Future
中的andThen
,后面的andThen的所有闭包总是从原来的Future
接收结果。
Future{
1
}.andThen{ case Success(x) =>
println(x) // print 1
Thread.sleep(2000)
x * 2
}.andThen{ case Success(x) =>
println(x) // print 1
Thread.sleep(2000)
x * 2
}
比较
val func: Function1[Int, Int] = { x: Int =>
x
}.andThen { y =>
println(y) // print 1
y * 2
}.andThen { z =>
println(z) // print 2
z * 2
}
func(1)
让 Future::andThen(s) 从原始 Future 接收所有相同结果而不是链接 Future 的原因是什么?我观察到这些链式andThen会顺序执行,所以可能不是为了并行目的。
scala.concurrent.Future
是两种异步方法的折衷方案:
Applies the side-effecting function to the result of this future, and returns a new future with the result of this future.
所以 andThen
很可能来自 OOP 领域。要获得与 Function1.andThen
类似的结果,您可以使用 map
方法:
Future(1).map {_ * 2}.map {_ * 2}
andThen
与 onComplete
有一点不同:andThen
的结果 Future 仍然 return 相同的结果,但会等到提供的观察者 return 或扔东西。这就是为什么在文档中写道:
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.
所以它对新 Future
的结果完全没有任何作用。甚至不能用它自己的例外来破坏它。 andThen
和 onComplete
只是观察者的顺序和并行绑定。
让我总结一下这个精彩的讨论。
比如说,我们有 tf: Future[T] =...
,还有两个函数,f: T => U
和 g: U => V
我们可以做到vf: Future[V] = tf map f map g
,和vf: Future[V] = tf map (f andThen g)
在另一个用例中,有 fp: PartialFunction[T, U]
和 gp: PartialFunction[U, V]
,
我们可以 运行 tf1: Future[T] = tf andThen fp andThen gp
- 这些部分函数将根据 tf 产生的值调用,没有外部影响 - 只会产生副作用。此序列在调用 gp
.
fp
还有一个 future 操作,onComplete,是这样工作的:有 f: Try[T] => U
,即使 future 以错误结束,调用 tf onComplete f
也会调用 f
; tf onComplete f
的结果是 Unit
.
此外,如果您的函数 f
生成 Future
,您将需要使用 flatMap
.