Как мне почистить этот уродливый кусок кода Scala - PullRequest
0 голосов
/ 15 апреля 2020

Это действительно простой вариант использования, но я не нахожу никакого изящного способа справиться с этим.

Ниже того, что я пытаюсь сделать. Это довольно явно ...

Примечание: users.byEmail возвращает Future[Option[User]].

override def invokeBlock[A](request: Request[A], block: UserRequest[A] => Future[Result]): Future[Result] = {
  val useEmail: Option[String] = request.session.get("userEmail")
  if (useEmail.isEmpty) {
    return Future.successful(Results.Unauthorized(("No email")))
  }
  val user: Option[User] = Await.result(users.byEmail(useEmail.get), Duration(1, TimeUnit.MINUTES))
  if (user.isEmpty) {
    return Future.successful(Results.Unauthorized(("No user")))
  }
  block(UserRequest(user.get, request))
}

Каков «правильный» способ написать это?

1 Ответ

5 голосов
/ 15 апреля 2020

Вот более чистая версия:

def invokeBlock[A](request: Request[A], block: UserRequest[A] => Future[Result]): Future[Result] =
  request.session.get("userEmail") match {
    case None =>
      Future.successful(Results.Unauthorized(("No email")))
    case Some(useEmail) =>
      users.byEmail(useEmail).flatMap {
        case None =>
          Future.successful(Results.Unauthorized("No user"))
        case Some(user) =>
          block(UserRequest(user, request))
      }
  }

Ключевые изменения:

Использование match вместо if на Option класс

Дон ' t return, это редко необходимо и может не выполнять то, что вы думаете

Используйте flatMap на Future вместо Await.result, чтобы избежать блокировки

...