2016-11-14 8 views
0

Что такое шаблон используется в Scala для решения сценария:Scala Узор: Для Понимания, что дает будущее [A]

у вас есть куча фьючерсов (они могут быть что угодно, но ради примера ...)

val aF = Future { true } 
val bF = Future { Option(3) } 
val cF = Future { myObject } 

и у вас есть некоторая функция, которая возвращает будущее,

def fooF: Future[SomeObject] 

Я хочу сделать что-то вроде:

for { 
    a <- aF 
    b <- bF 
    c <- cF 
} yield { 
    if (a) { 
     // do stuff with b & c 
     fooF 
    } else { 
     Future.successful(SomeObject) 
    } 
} 

Я хочу вернуть значение Future[SomeObject], но я называю FOOF внутри заявления выход, я получаю Future[Future[SomeObject]]

+1

Назначьте «внутреннее» Будущее в использовании для использования '<-' перед урожаем. Попытайтесь реорганизовать с помощью вложенного flatMap, чтобы понять. – cchantep

+0

@cchantep не будет запускать будущее, прежде чем я его использую? Я не хочу, чтобы будущее начинало исполнять, пока я его не назову ... что может быть никогда. –

+0

. Вы должны больше узнать о понимании/flatMap/Future – cchantep

ответ

2

Вот еще одно решение:

def doStuffWith(a: A, b: B, c: C): Future[SomeObject] = if (a) { 
    // do stuff with b & c 
    fooF 
} else Future.successful(SomeObject) 

for { 
    a <- aF 
    b <- bF 
    c <- cF 
    d <- doStuffWith(a, b, c) 
} yield d 

Как обсуждалось в @laughedelic ответе, это субъективное мнение, но я считаю, что этот способ является более читабельным и поддерживаемым (например, всегда выполнять функцию, чтобы проверить его).

-2
  • В Scala 2.12 Future имеет flatten метод:

    Создает новое будущее с одним слоем вложенности, этот метод эквивалентен flatMap (identity).

    Итак, вы можете написать for { ... } yield { ... } flatten.

  • В Scala < 2.12 вы можете достичь того же с flatMap(identity) (как упоминалось выше)


Альтернативное решение состоит в использовании flatMap а не для-понимания:

aF.flatMap { a => 
    if (a) { 
    (bF zip cF).flatMap { (b, c) => 
     // do stuff with b & c 
     fooF 
    } 
    } else 
    Future.successful(SomeObject) 
    } 
} 
+0

Сглаживание не должно происходить в случае – cchantep

+0

Хотя это новое сглаживание в Scala 2.12 наиболее приветствуется ради алгебры, я бы согласился с @cchantep: оператор 'if' действительно является другим« Будущим »в последовательности описанных вычислений по-осознанию, и должны быть поставлены на том же уровне, что и другие вычисления. В качестве ответа на (образец Scala) я поэтому не согласен с этим. –

+0

@cchantep вы могли бы разработать? что не так с 'flatten'? – laughedelic