2013-08-27 67 views
0

我已經概述了下面的問題。方法calculate表示異步運行subCalc1subCalc2的計算結果,以及將從最後兩個「子」計算結果中傳遞的mainCalc。重要的是,在開始這些計算之前,初步計算isCalcNecessary是返回一個布爾值。如果爲true,則計算將繼續並最終返回Future [某些[結果]]。如果初步計算返回false,則應返回Future [None],以說明計算不是必需的。這個小算法應該是最大不同步的。斯卡拉異步計算練習

def isCalcNecessary:Future[Boolean] = ... 
def subCalc1(param:Param):Future[SubResult1] = ... 
def subCalc2(param:Param):Future[SubResult2] = ... 
def mainCalc(subResult1:SubResult1, subResult2:SubResult2):Future[Result] = . 

def calcute(param:Param):Future[Option[Result]] = for { 
    necessary <- isCalcNecessary(param) 
    if necessary // this illustration fails at runtime if 'necessary' is false 
    subResult1 <- subCalc1(param) 
    subResult2 <- subCalc2(param) 
    result <- mainCalc(subResult1, subResult2) 
} yield Some(result) 

上圖未能以與(NoSuchElementException: Future.filter predicate is not satisfied (Future.scala:312))運行時,如果該條件if necessary不滿足。

你會怎麼寫這個算法?

回答

2
isCalcNecessary(param).flatMap { necessary => 
    if (necessary) 
    for { 
     subResult1 <- subCalc1(param) 
     subResult2 <- subCalc2(param) 
     result <- mainCalc(subResult1, subResult2) 
    } yield Some(result) 
    else 
    future(None) 
} 
2

另一種選擇是,以鳥巢爲,內涵

def calculate(param:Param):Future[Option[Result]] = for { 
    necessary <- isCalcNecessary(param) 
    endResult <- if (necessary) for { 
     subResult1 <- subCalc1(param) 
     subResult2 <- subCalc2(param) 
     result  <- mainCalc(subResult1, subResult2) 
    } yield Some(result) 
    else future(None) 
} yield endResult