这是一个理论问题。我有一个服务可以调用来完成工作,但该服务可能无法完成所有工作,因此我需要调用第二个服务来完成它。
我想知道是否有办法在没有 Await.result
的情况下做类似的事情map 函数中的结果:
val myFirstFuture = asyncRequestA()
myFirstFuture.map(result => {
result match {
case isWhatIExpected => result
case isNot => Await.result(asyncRequestB(), someDuration)
}
})
我想“合并”
asyncRequestB()
给出的 future 进入 myFirstFuture
不使用 Await 函数来获取结果。有任何想法吗?
最佳答案
Future
是一个单子(monad)。在 Scala 中使用 monad 的标准方法是使用“理解”:
for {
firstResult <- firstFuture
secondResult <- firstResult match {
case isWhatIExpected => Future.successful( firstResult )
case isNot => asyncRequestB()
}
}
yield secondResult
在 Scala 中,“理解”是一系列
flatMap
的语法糖。 , map
和 filter
方法应用程序和引擎盖下,编译器会将这种理解扩展为与 Regis 的答案相同的内容。尽管在这种情况下,您可能无法完全看到使用“for comprehension”语法的好处,但当您插入另一个
Future
时当事情开始变得棘手时,它就会大放异彩。 “用于理解”基本上所做的是将这三个方法应用程序的其他多层嵌套扁平化。其次,还有一种方法可以通过使用“部分函数”在语法上优化 Regis 的解决方案:
myFirstFuture.flatMap{
case r if isWhatIExpected( r ) => Future.succesful( r )
case r if isNot( r ) => asyncRequestB()
}
关于scala - Future[Future[T]] 到 Future[T] 在另一个 Future.map 中而不使用 Await?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16809881/