これから学んだandThen
の意味 answer は関数作曲家です。
と言う
_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からすべて同じ結果を受け取る理由は何ですか?これらのチェーニングされたandThenは順次実行されることがわかりました。その理由は、並列目的ではない可能性があります。
scala.concurrent.Future
は、2つの非同期アプローチの妥協案として設計されています。
読み込み中 Future.andThen
のドキュメント :
副作用関数をこのフューチャーの結果に適用し、このフューチャーの結果を持つ新しいフューチャーを返します。
したがって、andThen
は、OOP universeからのものである可能性が高いです。Function1.andThen
と同様の結果を得るには、 map
を使用できます。方法 :
Future(1).map {_ * 2}.map {_ * 2}
andThen
はonComplete
とは少し異なります。結果として生じるFuture of andThen
は同じ結果を返しますが、指定されたオブザーバーが何かを返すかスローするまで待機します。それがドキュメントに書かれている理由です:
このメソッドにより、コールバックが指定された順序で実行されるように強制できます。
また、ドキュメントの3行目に注意してください。
チェーンされたandThenコールバックの1つが例外をスローした場合、その例外は後続のandThenコールバックに伝播されないことに注意してください。代わりに、後続のandThenコールバックには、このフューチャーの元の値が与えられます。
そのため、新しいFuture
の結果はまったく何もしません。それ自身の例外でそれを台無しにすることさえできませんでした。このandThen
およびonComplete
は、オブザーバーの順次および並列バインディングのみです。
この素敵な議論をまとめてみましょう。
たとえば、tf: Future[T] =...
と、f: T => U
とg: U => V
という2つの関数があるとします。
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
を使用する必要があります。