2016-07-18 14 views
2

我有一種情況,我想同時執行多個任務作爲未來,以便如果其中一個失敗,其他人仍然會執行。 如果有人失敗,我想記錄它的錯誤。 我希望我的父線程能夠判斷每個線程是否成功,然後根據該線程執行某些操作。例如,如果期貨的一個失敗,打印「嘿,期貨的一個失敗」斯卡拉期貨。如果其中一個失敗,則採取行動

val futureA = Future(doTaskThatReturnsABoolean) 
val futureB = Future(doTaskThatReturnsABoolean) 
val futureC = Future(doTaskThatReturnsABoolean) 

futureA.onFailure (case t => println(future A failed) + t.getMessage) 
futureB.onFailure (case t => println(future B failed) + t.getMessage) 
futureC.onFailure (case t => println(future C failed) + t.getMessage) 

if (one of these futures failed) { 
    println("One of the futures failed") 
    throw new someNewError 
} 

如果任何或所有期貨失敗,我希望得到他們的堆棧跟蹤記錄,但我不想然後導致我的整個計劃出錯,直到所有的期貨都有機會運行。因爲他們都可能因爲不同的原因而出錯,我不想重複他們的錯誤,我想拋出一個新的錯誤。

我一直在閱讀http://docs.scala-lang.org/overviews/core/futures.html,但只是無法讓我的頭圍繞這一個。

我不想使用「等待」,因爲這需要一段時間,我希望給期貨儘可能多的時間,因爲他們想要運行。現在讓我們假設他們「將」完成,但在一個完全取決於數據大小的未確定時間範圍內。

回答

4

應該是這樣的:

val futureA = Future(doTaskThatReturnsABoolean).recoverWith{ 
    case e:Throwable => println(future A failed) + t.getMessage; Future.failed(e) 
} 
val futureB = Future(doTaskThatReturnsABoolean).recoverWith{ 
    case e:Throwable => println(future B failed) + t.getMessage; Future.failed(e) 
} 
val futureC = Future(doTaskThatReturnsABoolean).recoverWith{ 
    case e:Throwable => println(future failed) + t.getMessage; Future.failed(e) 
} 

val futures = List(futureA, futureB, futureC) 
Future.sequence(futures).recoverWith{ 
    case p:Throwable => println("One of the futures failed"); Future.failed(new SomeNewError) 
} 

Future.sequence輔助方法,轉換期貨的集合到一個未來的包裹結果的收集。如果其中一個來源期貨失敗,將導致未來失敗。

+0

謝謝!這很有用。我稍微修改,以獲得我想要的,因爲我想要拋出新的錯誤。 'Future.sequence(futures).onFailure {' 'throw new SomeNewError' '}' –

+0

歡迎您:) –

+0

在onFailure中投擲並不符合您的想法 –