我正在使用twitter finagle
框架,并给出了将来的可选选项序列,我希望根据选项的状态对其进行过滤。
seqFuture : Seq[Future[Option[Foo]]]
val filteredFuture = seqFuture map { fut => fut map {
opt => if(opt.isDefined) bar(opt.get)
}
}
函数bar : Foo => Bar
可以是身份,但是我不想返回Option[Bar]
。如果未定义期权,则我希望期货默默地失败,并且只对包含已定义期权的期货进行进一步的处理。
我尝试了flatten, flatMap, match case Some(_) =>
的组合,但是没有过滤它们。如果我在未定义期权的情况下抛出Exception
,则所有期货处理都会失败(因为我有时会收集它们)
使用finagle框架过滤和链接期货的替代解决方案仍然值得赞赏。
答案 0 :(得分:5)
此处map
两层的问题(首先是Seq
,然后是Future
)是,这种方法不允许您“跳过”计算的期货空选项。
如果使用Future.collect
(请注意,标准库和其他API调用此操作sequence
),则可以单行执行,最后得到{{1} },这总是比Future[Seq[...]]
更好的东西:
Seq[Future[...]]
如果您确实需要从def filteredFuture: Future[Seq[Foo]] = Future.collect(seqFuture).map(_.flatten)
转到Seq[Future[Option[Foo]]]
(而不是Seq[Future[Foo]]
的{{1}}),那么您有点不走运。如果您愿意使用任何Future[Seq[Foo]]
值导致期货失败,则可以这样做,但是当您沿行调用collect
之类的东西时,如果希望它们保持沉默,它们会炸毁忽略,则必须显式处理这些故障。我强烈建议您使用None
并直接转到collect
。