【问题标题】:What are the various patterns that I could handle a Future[Option[user]]?我可以处理 Future[Option[user]] 的各种模式是什么?
【发布时间】:2015-12-06 12:40:59
【问题描述】:

我有一个返回 Future[Option[User]] 的方法

def insertUser(...): Future[Option[User]] = { ... }

在我的控制器中,我目前正在这样做:

val futureUser = userService.insertUser(...)

我可以处理 Scala 中的哪些模式以最终返回 Option[User]?

【问题讨论】:

    标签: scala playframework future


    【解决方案1】:

    处理 monad (Future) 包装另一个 monad (Option) 的数据结构的最佳方法是使用 Monad Transformer(我假设你对 monad 的一般概念很熟悉)。

    例如,我们可以制作monad转换器OptionT

    final case class OptionT[F[_], A](run: F[Option[A]]) {
      def fold[X](some: A => X, none: => X)(implicit F: Functor[F]): F[X] = 
        F.map(run) {
          case None => none
          case Some(a) => some(a)
        }
    }
    

    然后,我们可以像这样对内部 monad (Option) 进行操作:

    val futureOption = OptionT(Future(Right("Yes")))
    
    futureOption.fold(identity, "No") // Future[String]: Future("Yes")
    

    如您所见,使用 monad 转换器 (Future[Option[A]] => Future[A]) 处理内部 monad 非常简单

    但要回答您的问题,要从Future[Option[User]] 返回Option[User],您将不可避免地需要使用Await.result 之类的东西来阻止,当然这非常不鼓励。

    在 Web 服务器上下文中的应用程序代码中,通过利用 monad 转换器,您永远不必从开始(收到请求)到结束(发送响应)离开上下文 Future > 像上面那样。

    关于播放框架,可以使用Action.async方法直接传递Future[A]作为响应。

    【讨论】:

    • 我有依赖于其他数据库调用的数据库调用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-18
    • 1970-01-01
    相关资源
    最近更新 更多