未来[期权[未来[Int]]]到未来[期权[Int]]

Future[Option[Future[Int]]] to Future[Option[Int]]

Scala 中从 Future[Option[Future[Int]]] 转换为 Future[Option[Int]] 的最简洁的方法是什么?有可能吗?

有两个嵌套的 Future 可以合并为一个,因此需要 flatMap

def flatten[A](f: Future[Option[Future[A]]]): Future[Option[A]] =
  f.flatMap({
    case None => Future.successful(None)
    case Some(g) => g.map(Some(_))
  })

或者,更简洁地说:

def flatten[A](f: Future[Option[Future[A]]]): Future[Option[A]] =
  f.flatMap(o => Future.sequence(o.toSeq).map(_.headOption))

感谢@lmm 对此想法的回答。理想情况下,这可以写成 f.flatMap(Future.sequence),但不幸的是 sequence 期望 TraversableOnceOption 不会扩展。

最干净的方法可能是使用 scalaz:

import scalaz.std.option._
import scalaz.std.scalaFuture._
import scalaz.syntax.traverse._

//assuming implicit execution context in scope

f.flatMap(_.sequence)

你问的是如何通过编码摆脱一些纸袋,你已经得到了一些关于如何做到这一点的很好的答案,但是你应该退后一步,尽量不要进入你所在的纸袋目前在。在这里查看我的回答:Get rid of Scala Future nesting 关于如何避免进入 Future[X[Future[y]] 类型签名,这样您就不必弄清楚如何退出它。