为什么未来的andThen没有链接结果?

时间:2015-06-05 06:07:28

标签: scala future

我从这个answer学到的andThen意思是一个函数作曲家。

说那个

f andThen g andThen h

将等于

h(g(f(x)))

这意味着h function将收到来自g(f(x))

的输入

但对于andThen中的Future,以下所有关闭,然后始终会收到原始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的原因是什么?我观察到这些链接然后将按顺序执行,因此原因可能不是为了并行目的。

2 个答案:

答案 0 :(得分:21)

scala.concurrent.Future旨在妥协两种异步方法:

  1. 面向对象的observer,允许绑定异步处理程序
  2. 功能monad,提供丰富的功能组合功能。
  3. 阅读Future.andThen's docs

      

    将副作用函数应用于此未来的结果,并且   这个未来的结果将带来一个新的未来。

    所以andThen最有可能来自OOP宇宙。要获得与Function1.andThen类似的类似结果,您可以使用map方法:

    Future(1).map {_ * 2}.map {_ * 2}
    

    andThenonComplete的区别在于一件小事:andThen的未来仍然会返回相同的结果,但会等到提供的观察者返回或抛出一些东西。这就是文档中写的原因:

      

    此方法允许强制执行回调在a中执行   指定的顺序。

    另请注意文档中的第三行:

      

    请注意,如果其中一个链接的andThen回调引发异常,   该异常不会传播到后续的andThen回调。   相反,后续的andThen回调将被赋予原始值   这个未来。

    所以它对新Future的结果完全无效。甚至无法用它的例外来破坏它。这个andThenonComplete只是观察者的顺序和并行绑定。

答案 1 :(得分:1)

让我总结一下这个很好的讨论。

说,我们有tf: Future[T] =...和两个函数,f: T => Ug: 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产生的值上调用,没有外部效应 - 只会发生副作用。在调用fp之前,此序列等待gp

另一个未来的操作onComplete就是这样的:拥有f: Try[T] => U,即使未来以错误结束,调用tf onComplete f也会调用f; tf onComplete f的结果是Unit类型。

此外,如果您的函数f生成Future,则需要使用flatMap