如何将Future[Option[X]]
转换为Option[Future[X]]
?
val futOpt:Future[Option[Int]] = future(Some(1))
val optFut:Option[Future[Int]] = ?
更新
这是this question的后续行动。我想我正试图抓住优雅地改造嵌套的未来。我正试图通过Option
来实现Seq
uces可以做什么,您可以将Future[Seq[Future[Seq[X]]]]
转换为Future[Future[Seq[Seq[x]]]]
,然后转换为flatMap
双层。正如Ionut澄清的那样,我按照翻转的顺序表达了这个问题,它应该是Option[Future[X]]
- > Future[Option[X]]
。
答案 0 :(得分:31)
不幸的是,如果不丢失计算的非阻塞属性,这是不可能的。如果你想一想就很简单。在None
完成之前,您不知道计算结果是Some
还是Future
,因此您必须Await
。那时,再拥有Future
是没有意义的。您只需返回Option[X]
,因为Future
已经完成。
看看这里。它总是返回Future.successful
,它不进行任何计算,只是将o
包裹在Future
中,没有充分的理由。
def transform[A](f: Future[Option[A]]): Option[Future[A]] =
Await.result(f, 2.seconds).map(o => Future.successful(o))
所以,如果在你的上下文中有意义阻止,你最好使用它:
def transform[A](f: Future[Option[A]]): Option[A] =
Await.result(f, 2.seconds)
评论回复:
def transform[A](o: Option[Future[A]]): Future[Option[A]] =
o.map(f => f.map(Option(_))).getOrElse(Future.successful(None))
答案 1 :(得分:0)
从技术上讲你可以做到这一点,唯一的条件是你有一个支持空的类型的类型类(例如 Monoid)
def fut2Opt[A: Monoid](futOpt: Future[Option[A]])(implicit ec: ExecutionContext): Option[Future[A]] =
Try(futOpt.flatMap {
case Some(a) => Future.successful(a)
case None => Future.fromTry(Try(Monoid[A].empty))
}).toOption