从Scala期货列表中提取成功的最简单方法是什么?

时间:2015-11-03 18:02:05

标签: scala

假设我们有一系列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 } }

有没有更简单的方法来编写上述内容?

1 个答案:

答案 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