这是一个非常简单的用例,但我没有找到任何优雅的方法来处理它。
下面是我正在尝试做的事情。说的很清楚了...
注意: 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))
}
Run Code Online (Sandbox Code Playgroud)
写这个的“正确”方法是什么?
这是一个更干净的版本:
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))
}
}
Run Code Online (Sandbox Code Playgroud)
关键的变化是
使用match而不是if在Option课堂上
不要使用return,这很少有必要,并且可能不会做您认为的事情
使用flatMap上Future,而不是Await.result以避免阻塞