假设我们有一系列Scala Future
结果,例如val futures: Seq[Future[Boolean]]
,让我们说我想要一个返回第一个Future[Boolean]
结果的true
,但是否则失败或正常返回false。
目前我所拥有的实现是这样的:
// convert to Seq[Future[Try[Boolean]]]
val tries = futures.map{ _.map(Success(_)).recover{ case t: Throwable => Failure(t) } }
val sequence = Future.sequence(tries)
// first positive
val positive = sequence.map{ _.find{ case Success(true) => true; case _ => false } }
val nonpositive = sequence.map{ _.find{ case Success(true) => false; case _ => true } }
// prioritise positive results over other results
val futureTry =
for {
p <- positive
n <- nonpositive
} yield( p.orElse(n) )
// convert from Future[Try[Boolean]] back to Future[Boolean]
val future = futureTry.map { _.map { t => t.get } }
有没有更简单的方法来编写上述内容?
答案 0 :(得分:1)
您可以使用Future.find
,因为您正在寻找Boolean
,所以您可以传递identity
功能:
import scala.concurrent.Future
val failedF = Future.failed[Boolean](new Exception("boo"))
val falseF = Future.successful(false)
val trueF = Future.successful(true)
val f1 = Future.find(trueF :: falseF :: failedF :: Nil)(identity)
val f2 = Future.find(falseF :: failedF :: Nil)(identity)
val f3 = Future.find(failedF :: Nil)(identity)
Future.sequence(f1 :: f2 :: f3 :: Nil).foreach(println)
// List(Some(true), None, None)
它会返回Future[Option[Boolean]]
,但您可以通过提供Future[Boolean]
的默认值轻松将其转换为getOrElse
:
f2.map(_.getOrElse(false)).foreach(println)
// false