#scala #future #for-comprehension
Вопрос:
У меня есть список заданий для понимания:
def main = {
List("en", "es", "de").foreach(c => execAll(c))
}
def execAll(country: String): Future[Unit] = {
for {
_ <- repo.exec1(country)
_ <- repo.exec2(country)
_ <- repo.exec3(country)
_ <- repo.exec4(country)
_ <- repo.exec5(country)
} yield ()
}
Проблема сейчас в том, что мне нужно выполнять функции exec4
и exec5
только для стран «en» и «es».
Я попытался добавить функции в список фьючерсов по условию ( if country == "en"
не добавляйте его).
val all = for {
_ <- repo.exec1(country)
_ <- repo.exec2(country)
_ <- repo.exec3(country)
} yield ()
val enOrEsOnly = for {
_ <- repo.exec4(country)
_ <- repo.exec5(country)
} yield ()
country match {
case "de" => all
case other => all enOrEsOnly // invalid code
}
Можете найти решение, используя for-comprehension
здесь? Или можно просто воспользоваться списком фьючерсов здесь? Мне не нужны их результаты. Спасибо
Или я могу просто использовать an if
, чтобы решить эту проблему:
if (country != "de") {
repo.exec4(country)
repo.exec5(country)
}
Комментарии:
1. Этот код
all enOrEsOnly
можно заменить плоской картой:all.flatMap(_ => enOrEsOnly)
Ответ №1:
Как насчет заменить execAll
на:
def execAll(country: String): Future[Unit] = {
for {
_ <- repo.exec1(country)
_ <- repo.exec2(country)
_ <- repo.exec3(country)
if country != "de"
_ <- repo.exec4(country)
_ <- repo.exec5(country)
} yield ()
}
Комментарии:
1. Обратите внимание, что в этом случае работа
Future
будет завершена с ошибкой. Это означает, что если результат этой функции затем будет составлен с использованиемmap
, иflatMap
он замкнется.
Ответ №2:
Я бы предпочел добавить дополнительный слой, на repo
котором есть проверки, таким образом, ваш код будет таким же, и в этом дополнительном слое вы сделаете что-то вроде этого:
final class Domain(repo: Repository) {
def exec4(country: String): Future[Unit] =
country match {
case "en" | "es" => repo.exec4(country)
case _ => Future.unit
}
}
Комментарии:
1. Тнх. Я выбрал решение @esse для простоты, но поддержал ваш ответ за хорошее объяснение. Кроме того, я видел ваш комментарий к его посту, и его следует принять во внимание.