このような問題に直面した場合、理解のために異なる型を使用したい場合、1 つの解決策は、型の 1 つを選択して、もう 1 つの型をそれにマップすることです。あなたの状況では、先物の一意のプロパティ (非同期) を考えるFuture
と、最小公分母として を選択し、 を にマップしTry
ますFuture
。次のように簡単に実行できます。
val result = for{
a <- someFuture
b <- tryToFuture(processResult(a))
} yield b
result.map { /* Success Block */ } recover { /* Failure Block */ }
def tryToFuture[T](t:Try[T]):Future[T] = {
t match{
case Success(s) => Future.successful(s)
case Failure(ex) => Future.failed(ex)
}
}
これが非常に一般的な状況であり、明示的な変換を常に追加する必要がない場合は、tryToFuture
メソッドをヘルパー オブジェクトで暗黙的に定義し、次のように必要な場所にインポートできると思います。
object FutureHelpers{
implicit def tryToFuture[T](t:Try[T]):Future[T] = {
t match{
case Success(s) => Future.successful(s)
case Failure(ex) => Future.failed(ex)
}
}
}
import FutureHelpers._
val result = for{
a <- someFuture
b <- processResult(a)
} yield b
result.map { /* Success Block */ } recover { /* Failure Block */ }
Future.success
andの呼び出しは、内部で別のタスクをサブミットするという点で、スコープ内にあるものFuture.failed
すべてに影響を与えることを覚えておいてください。ExecutionContext
編集
Viktor がコメントで指摘したように、aTry
を aに変換するプロセスは、以下の更新された例のようにFuture
使用するだけでさらに簡単になります。Future.fromTry
val result = for{
a <- someFuture
b <- Future.fromTry(processResult(a))
} yield b
result.map { /* Success Block */ } recover { /* Failure Block */ }
これはおそらく、暗黙的な処理を行ったり、独自の変換ロジックを展開したりするのと比較して、最善の策です。