2017-04-18 27 views
0

我有一個返回Future [Try [Option [Int]]]的方法。我想提取Int的值作進一步的計算。任何想法如何處理?在scala中處理未來[嘗試[選項]]

+0

試圖理解你爲什麼有前途[嘗試[選項[INT]]。如果您同時選中「未來」,請嘗試使用方法轉到「選項」,然後您可以嘗試將來自方法組合的結果映射到單個未來 –

+0

我同意@FabioFumarola。必須處理這種類型是非常不幸的。 – mfirry

+1

正確答案在很大程度上取決於您如何處理未來的錯誤案例,嘗試和無。請在此添加更多詳細信息。 – nmat

回答

1

只是map未來,用匹配的情況下,以處理不同的情況:

val result: Future[Try[Option[Int]]] = ??? 
result.map { 
    case Success(Some(r)) => 
    println(s"Success. Result: $r") 
    //Further computation here 

    case Success(None) => //Success with None 
    case Failure(ex) => //Failed Try 
} 
1

轉換Future[Try[Option[Int]]]Future[Int]

一個哈克的方式是不利的成果轉化爲失敗的未來和flatMapping過。

將嘗試失敗轉換爲將來的失敗,保留異常源自的信息嘗試並將None轉換爲NoneFound異常。

val f: Future[Try[Option[Int]]] = ??? 

case class TryException(ex: Throwable) extends Exception(ex.getMessage) 
case object NoneFound extends Exception("None found") 

val result: Future[Int] = f.flatMap { 
    case Success(Some(value)) => Future.successful(value) 
    case Success(None) => Future.failed(NoneFound) 
    case Failure(th) => Future.failed(TryException(th)) 
} 

result.map { extractedValue => 
    processTheExtractedValue(extractedValue) 
}.recover { 
    case NoneFound => "None case" 
    case TryException(th) => "try failures" 
    case th => "future failures" 
} 

現在在任何情況下,您都知道異常來自何處。如果沒有發現異常,你知道未來和嘗試是成功的,但選項是沒有的。這樣信息不會丟失,並且嵌套結構被平化爲Future[Int]

現在結果類型爲Future[Int]。只需使用map,flatMap,recover和recoverWith來編寫進一步的動作。

2
future.map(_.map(_.map(i => doSomethingWith(i)))) 
0

如果你想使用cats你可以做的樂趣(的樂趣某些定義)之類的東西:

import scala.concurrent._ 
import scala.util._ 
import scala.concurrent.ExecutionContext.Implicits.global 

import cats.Functor 
import cats.instances.option._ 
import cats.implicits._ 

val x = Future { Try { Some(1) } } // your type 

Functor[Future].compose[Try].compose[Option].map(x)(_ + 2) 

這個建議只有在你已經很熟悉的貓或scalaz。 否則,你很高興與其他有效的答案一起出發(我特別喜歡地圖 - 地圖一)。

0

如果你真的關心解壓請看看這個,否則通過@pamu來回答你的問題,看看你是如何真正使用你的未來。

假設您的未來值爲result

Await.ready(result, 10.seconds).value.get.map { i => i.get}.get

顯然,這不會通過你的失敗,並沒有得到案件,並會拋出異常,不建議等待。

所以,如果你想處理故障和無案例 - >

val extractedValue = Await.ready(f, 10.seconds).value.get match { 
case Success(i) => i match { 
    case Some(value) => value 
    case None => println("Handling None here") 
} 
case Failure(i) => println("Handling Failure here") 
}