我在我的代碼中有一個場景,我需要根據包含特定值的成功結果使Future
失敗。我可以通過flatMap
完成這項工作,但我想知道是否有更簡單的方法來完成這項工作。首先,非常簡單的例子:基於成功的結果失敗未來
import concurrent._
case class Result(successful:Boolean)
object FutureTest {
def main(args: Array[String]) {
import ExecutionContext.Implicits._
val f = Future{Result(false)}.flatMap{ result =>
result match{
case Result(false) => Promise.failed(new Exception("The call failed!!")).future
case _ => Promise.successful(result).future
}
}
f onFailure{
case x => println(x.getMessage())
}
}
}
所以這裏我舉的例子,我想如果Future
返回Result
有其成功指示器的false
值失敗。正如我所說,我可以使這項工作好與flatMap
,但我想消除的代碼行是:
case _ => Promise.successful(result).future
這種說法似乎沒有必要。我想要的行爲是能夠定義條件,如果它的計算結果爲真,允許我返回一個與我一樣不同的Future
,但如果不是這樣,就把事情保持原樣(有點像PartialFunction
語義。有沒有辦法做到這一點,我只是沒有看到?我看collect
和transform
和那些似乎不成爲合適人選任。
編輯
後從@Rex Kerr和@senia獲得map
建議,我創建了一個PimpedFuture
,並隱式轉換爲代碼,類似如下:
class PimpedFuture[T](f:Future[T])(implicit ex:ExecutionContext){
def failWhen(pf:PartialFunction[T,Throwable]):Future[T] = {
f map{
case x if (pf.isDefinedAt(x)) => throw pf(x)
case x => x
}
}
}
隱含
implicit def futToPimpedFut[T](fut:Future[T])(implicit ec:ExecutionContext):PimpedFuture[T] = new PimpedFuture(fut)
而新的處理代碼:
val f = Future{ Result(false) } failWhen {
case Result(false) => new Exception("The call failed!!")
}
我認爲這是一個少許清潔劑,同時還利用使用map
建議。
你想在這兩種情況下*新*未來?或者只有在失敗的情況下? –
結果本身,在我的實際代碼中,是從調用返回給演員的。鑑於這種結果,我不希望該演員總是向上遊傳播失敗。它基於通過調用添加密鑰成功將值存儲到couchbase中。並不是所有的調用代碼都會關心成功標誌的值是否爲false;這是情景。 – cmbaxter
聽起來像['filter'](https://github.com/scala/scala/blob/v2.10.1/src/library/scala/concurrent/Future.scala#L306)方法。 – senia