составлено для понимания в scala

#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 для простоты, но поддержал ваш ответ за хорошее объяснение. Кроме того, я видел ваш комментарий к его посту, и его следует принять во внимание.