2015-11-03 71 views
0

假设我们有一个Scala Future结果的序列,比如val futures: Seq[Future[Boolean]],我们假设我想获得一个返回第一个true结果的Future[Boolean],但是否则它会失败或返回false。从Scala期货列表中提取成功的最简单方法是什么?

目前目前实施我已经是这样的:

// 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

您可以使用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  
+0

看起来不错,它的实施缺乏上述的唯一的事情是,如果没有找到成功的故障必须传播。在上面的内容中,我们只是放弃了任何失败,因为它们被转换为“无”。有没有简单的方法呢? –

+0

一种可能的方法是做类似于我最后一个例子的东西,但是返回失败的'Future',你用'Future.sequence'获得:'f3.flatMap(_。map(Future.successful _)。getOrElse(Future。序列(failedF :: Nil).map(_。head)))',但这看起来不太好。 –

相关问题