2013-08-27 71 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