The andThen
meaning I learned from this answer is a function composer.
Say that
f andThen g andThen h
will equal to
h(g(f(x)))
This implies the h function
will receive input from g(f(x))
But for the andThen
in Future
, all the closure of the following andThen always receives the result from the original 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
}
compare to
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)
What is the reason to make Future::andThen(s) receive all the same result from original Future instead of chaining Future? I've observed that these chained andThen will be executed sequentially, so the reason may not be for parallel purpose.
scala.concurrent.Future
is designed as compromise of two asynchronous approaches:
Reading Future.andThen
's docs:
Applies the side-effecting function to the result of this future, and returns a new future with the result of this future.
So andThen
is most likely from OOP universe. To gain similar similar result to Function1.andThen
you could use map
method :
Future(1).map {_ * 2}.map {_ * 2}
andThen
differs from onComplete
with one little thing: resulting Future of andThen
still returning same result, but will wait until supplied observer will return or throw something. That's why there is written in the docs:
This method allows one to enforce that the callbacks are executed in a specified order.
Also note third line from docs:
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.
So it' completely do nothing with new Future
's result. Could not even spoil it with it's ownt exception. This andThen
and onComplete
just sequential and parallel binding of observers.