2013-08-27 2 views
0

Я описал проблему ниже. Метод calculate представляет собой вычисление, которое должно выполняться как асинхронно subCalc1, так и subCalc2, и mainCalc, которые будут переданы из результатов двух последних «под» вычислений. Примечательно, что перед началом этих вычислений предварительный расчет isCalcNecessary - это возврат булева. Если значение true, вычисление продолжится и в конечном итоге вернет Future [Some [Result]]. Если предварительный расчет возвращает false, он должен вернуть Future [None], чтобы показать, что расчет не требуется. Этот небольшой алгоритм должен быть максимально асинхронным.Scala async расчет упражнений

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 
Смежные вопросы