2015-11-03 79 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)))',但這看起來不太好。 –

相關問題