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

Che*_* OT 21 scala future

andThen我从这个答案中学到的意思是一个函数作曲家.

比如说

f andThen g andThen h
Run Code Online (Sandbox Code Playgroud)

将等于

h(g(f(x)))
Run Code Online (Sandbox Code Playgroud)

这意味着h function将从中接收输入g(f(x))

但是对于andThenin 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
}
Run Code Online (Sandbox Code Playgroud)

相比于

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)
Run Code Online (Sandbox Code Playgroud)

是什么原因使Future :: andThen(s)从原始Future获得所有相同的结果而不是链接Future?我观察到这些链接然后将按顺序执行,因此原因可能不是为了并行目的.

Odo*_*ois 25

scala.concurrent.Future 被设计为两种异步方法的妥协:

  1. 面向对象的观察者,它允许绑定异步处理程序
  2. 功能monad,提供丰富的功能组合功能.

雷丁Future.andThen的文档:

将副作用函数应用于此未来的结果,并返回具有此未来结果的新未来.

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

Future(1).map {_ * 2}.map {_ * 2}
Run Code Online (Sandbox Code Playgroud)

andThen不同于onComplete与一个小东西:导致未来andThen仍返回相同的结果,但会等到供应观察者将返回或扔东西.这就是文档中写的原因:

此方法允许强制执行以指定顺序执行回调.

另请注意文档的第三行:

请注意,如果链接的andThen回调之一抛出异常,则该异常不会传播到后续的andThen回调.相反,后续的andThen回调将被赋予此未来的原始值.

所以它对新Future的结果完全没有任何作用.甚至无法用它的例外来破坏它.这andThenonComplete刚刚串行和并行观察员的结合.

  • 我可以说它是 onComplete 的另一个版本但返回“this”,以便它可以以链接方式绑定多个“观察者”回调处理程序? (2认同)