简体   繁体   中英

Scala async calculation exercise

I have outlined the problem below. Method calculate represents a calculation that is to run subCalc1 and subCalc2 asynchroniously, and mainCalc that will be passed results from the last two 'sub' calculations. Significantly, before starting these calculations a preliminary calculation isCalcNecessary is to return a Boolean. If true, the calculation will continue and eventually return Future[Some[Result]]. If preliminary calculation returns false, it should return Future[None], as to illustrate that calculation was not necessary. This small algorithm should be maximally asynchronious.

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)

The above illustration fails at runtime with ( NoSuchElementException: Future.filter predicate is not satisfied (Future.scala:312) ), if the if necessary conditional is not satisfied.

How would you write this algorithm?

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

Another option would be to nest for-comprehensions

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM