【问题标题】:Future[Future[T]] to Future[T] within another Future.map without using Await?Future[Future[T]] 到 Future[T] 在另一个 Future.map 中而不使用 Await?
【发布时间】:2013-05-29 19:08:40
【问题描述】:

这是一个理论问题。我有一个服务可以调用来完成一项工作,但该服务可能无法完成所有工作,因此我需要调用第二个服务来完成它。

我想知道是否有一种方法可以在没有 Await.result 地图函数中的结果的情况下执行类似的操作:

val myFirstFuture = asyncRequestA()

myFirstFuture.map(result => {
    result match {
       case isWhatIExpected => result
       case isNot => Await.result(asyncRequestB(), someDuration)
    }
})

我想将asyncRequestB() 给出的未来“合并”到myFirstFuture 中,而不使用Await 函数来获取结果。

有什么想法吗?

【问题讨论】:

    标签: scala asynchronous jvm scala-2.10


    【解决方案1】:

    Future 是一个单子。在 Scala 中使用 monad 的标准方法是使用“for comprehension”:

    for {
      firstResult <- firstFuture
      secondResult <- firstResult match {
        case isWhatIExpected => Future.successful( firstResult )
        case isNot => asyncRequestB()
      }
    }
    yield secondResult
    

    在 Scala 中,“用于理解”是一系列 flatMapmapfilter 方法应用程序的语法糖,在后台,编译器会将这种理解扩展为与 Regis 的答案相同的内容。

    虽然在这种情况下,您可能无法完全看到使用“for comprehension”语法的好处,但当您插入另一个 Future 并且当事情开始变得棘手时,它就会大放异彩。 “for comprehension”基本上所做的就是将这三个方法应用程序的其他多层嵌套扁平化。

    其次,还有一种方法可以在语法上优化 Regis 的解决方案,即利用“部分函数”:

    myFirstFuture.flatMap{ 
      case r if isWhatIExpected( r ) => Future.succesful( r )
      case r if isNot( r ) => asyncRequestB()
    }
    

    【讨论】:

    • 也非常感谢您的回答
    【解决方案2】:

    只需使用flatMap 而不是map

    myFirstFuture.flatMap{ result =>
      result match {
         case isWhatIExpected => Future.successful( result )
         case isNot => asyncRequestB()
      }
    }
    

    作为旁注,您甚至可以像这样缩短它:

    myFirstFuture.flatMap{
       case result: isWhatIExpected => Future.successful( result )
       case _ => asyncRequestB()
    }
    

    另请参阅 Nikita Volkov 的回答,了解使用 for comprehensions 的示例

    【讨论】:

    • Scala 2.13 以上,使用Future(Future(123)).flatten
    • @Jus12:似乎与提出的问题无关
    猜你喜欢
    • 2016-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-25
    • 1970-01-01
    • 2023-02-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多