`未来[选项[未来[选项[X]]]]`进入`未来[选项[X]]`

Dom*_*kis 5 scala

如何转化Future[Option[Future[Option[X]]]]Future[Option[X]]

如果它是一个TraversableOnce而不是Option我使用Future伴侣对象 ; 但是选项怎么样?

例:

def processAndReturnFuture(x:String):Future[String] = future(x)
def processAgainAndReturnOption(x:String):Option[String] = Some(x)

val futOpt:Future[Option[String]] = future(Some("x"))
val futOptFutOpt:Future[Option[Future[Option[String]]]] =
  futOpt.map( opt =>
    opt.map( x =>
      processAndReturnFuture(x).map( processedX =>
        processAgainAndReturnOption(processedX)
      )
    )
  )
Run Code Online (Sandbox Code Playgroud)

Ion*_*tan 7

更新的答案

这可能会成功.我所做的是mapflatMap最外面的Future一个和最外面的模式匹配替换你的前两个调用Option.

val futOptFutOpt: Future[Option[String]] =
  futOpt.flatMap {
    case None => Future.successful(None)
    case Some(x) =>
      processAndReturnFuture(x).map {
        processedX => processAgainAndReturnOption(processedX)
      }
  }
Run Code Online (Sandbox Code Playgroud)

初步答复

我假设您的代码中的某个地方有一个map将a Future[Option[A]]转换为a 的调用Future[Option[Future[Option[X]]]].将其替换map为a flatMap并删除Option结果中的最顶层.你最终会得到Future[Option[X]].这就是我的意思:

scala> import scala.concurrent._
import scala.concurrent._

scala> import ExecutionContext.Implicits.global
import ExecutionContext.Implicits.global

scala> val f1: Future[Option[Future[Option[String]]]] =
     | Future.successful(Some(1)).map(v => Some(Future.successful(Some(v.toString))))
f1: scala.concurrent.Future[Option[scala.concurrent.Future[Option[String]]]] = scala.concurrent.impl.Promise$DefaultPromise@6f900132

scala> val f2: Future[Option[String]] =
     | Future.successful(Some(1)).flatMap(v => Future.successful(Some(v.toString)))
f2: scala.concurrent.Future[Option[String]] = scala.concurrent.impl.Promise$DefaultPromise@2fac9a62
Run Code Online (Sandbox Code Playgroud)

关于你的实际情况我可能并不完全正确,但你可能会用几个maps 代替几个s来解决这个问题flatMap.