0

我已经概述了下面的问题。Methodcalculate表示要异步运行的计算,subCalc1并将传递最后两个“子”计算的结果。重要的是,在开始这些计算之前,初步计算是返回一个布尔值。如果为真,计算将继续并最终返回 Future[Some[Result]]。如果初步计算返回false,则应返回Future[None],以说明无需计算。这个小算法应该最大程度地异步。subCalc2mainCalcisCalcNecessary

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

你会怎么写这个算法?

4

2 回答 2

2
isCalcNecessary(param).flatMap { necessary => 
  if (necessary) 
    for {
      subResult1 <- subCalc1(param)
      subResult2 <- subCalc2(param)
      result <- mainCalc(subResult1, subResult2)
    } yield Some(result)
  else
    future(None)
}
于 2013-08-27T12:09:06.873 回答
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
于 2013-08-27T18:37:35.553 回答