2016-12-30 106 views
1

我期望下面的代碼將生成值5,因爲我已經寫回恢復來處理異常並返回5.但我總是看到IntelliJ中的異常。這裏有什麼錯誤?無法在未來恢復 - 斯卡拉

import scala.concurrent._ 
import scala.concurrent.ExecutionContext.Implicits.global 
import scala.util.{Failure, Success, Try} 
import scala.concurrent.duration._ 
import scala.language.postfixOps 

object ConcurrencyExample extends App { 

val time = System.currentTimeMillis() 

val futures1: Future[Int] = Future { 
    println("in Future.. sleeping") 
    Thread.sleep(10) 
    println("awakein future") 
    throw new Exception("future failed") 
    1 
} 

val result = futures1.map(x=>x+3) 
result recover { 
    case e:Exception => 5 
} 

result onComplete{ 
    case Success(v)=>println("result is "+v) 
    case Failure(e) =>println("failed result:"+e) 
} 

Await.result(result,100 millis) 

} 

結果

in Future.. sleeping 
awakein future 
Exception in thread "main" LegacyException: future failed 

回答

3

它不工作,因爲將來會做恢復是不是你在呼喚Await.result()之一。

Future's scaladoc,我們得知recover創建了一個新的未來,將處理這個未來可能包含的任何匹配throwable。如果沒有匹配,或者如果這個未來包含有效的結果,那麼新的未來將包含相同的結果。

因此,這將來你現在在感興趣

試試這個:

val result = futures1.map(x=>x+3) 
      .recover { 
       case e:Exception => 5 
      } 

Await.result(result,100 millis) 
+0

感謝。懷疑 - 地圖被稱爲未來1。我的理解是地圖只有在未來成功時纔會被調用。如果未來不成功,.recover將被稱爲期貨1?我對語法不熟悉。您正在呼叫futures1.map,但不是futures1.recover。這是OrElse嗎? –

+0

.map將返回一個新的未來,或者失敗,或者如果'futures1'成功,則應用傳遞的操作。 Scala的對象通常是不可改變的,任何看起來像是在修改某些東西的方法實際上都會返回一個新的實例並進行所需的修改。因此,在這裏,當'futures1'失敗時,恢復就會起作用。 – Shastick