当遇到这样的问题时,您想在理解中使用不同的类型,一种解决方案可以是尝试选择其中一种类型并将另一种类型映射到它。对于您的情况,鉴于期货的独特属性(异步),我会选择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
并对范围内的Future.failed
任何内容产生影响ExecutionContext
,因为它将在后台向其提交另一个任务。
编辑
正如 Viktor 在评论中指出的那样,如果您在下面的更新示例中使用 like,则将 a 转换Try
为 a的过程会更加容易:Future
Future.fromTry
val result = for{
a <- someFuture
b <- Future.fromTry(processResult(a))
} yield b
result.map { /* Success Block */ } recover { /* Failure Block */ }
这可能是你最好的选择,而不是使用隐式或滚动你自己的转换逻辑。