【问题标题】:How to handle a future option inside of a playframework controller?如何处理 playframework 控制器中的未来选项?
【发布时间】:2015-12-19 12:35:36
【问题描述】:

我的方法调用目前有以下签名:

val article:Future[Option[Article]] = articleService.getById(1)

我的控制器看起来像:

def show(id: Int) = Action.async { request =>
  articleService.getById(id).onSuccess {
    case articleOpt => {
      articleOpt.map{ 
         article => Ok("....")
      }
    }
  }
   Ok("fail")      
}

有没有更简洁的方式来处理Future[Option[Model]]

【问题讨论】:

    标签: scala playframework future


    【解决方案1】:
    def show(id: Int) = Action.async { request =>
      articleService.getById(id).map {
        case Some(article) => Ok(article) 
        case None => Ok("...")
      }.recover{case ex => Ok("fail")}
    }
    

    更清洁的方式需要使用像 scalaz 的 ReaderT 这样的技巧

    【讨论】:

    • 这是对的,但使用InternalServerError("fail")NotFound("...") 可能会更好。
    • @danielnixon 'case ex' 会抓住一切吗?那么我会在游戏中还是在全球范围内记录异常?
    • 可能吧,对打法不熟悉,建议以TS为例。但显然这个问题与只玩特定主题没有什么共同点
    • @Blankman 你会从 getById 方法的未来中捕捉到 excaptions,或者,也许是在一些 Ok 的构建过程中出现的
    【解决方案2】:

    你也可以使用 scalaz monad 转换器 OptionT:

    import scalaz.OptionT
    
    def show(id: Int) = Action.async { 
        OptionT(articleService.getById(id))
           .map(a => Ok(s"found: ${a.name}"))
           .getOrElse(NotFound("Not found"))
    }
    

    【讨论】:

    • import cats.data.OptionT一样
    【解决方案3】:

    可能是这样的

     def show(id: Int) = Action.async { request =>
      articleService.getById(id) map { op =>
            op match {
                case Some(acle) => Ok(s"found: ${acle.name}")
                case None => NotFound("Not found")                  
            }}
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-28
    • 1970-01-01
    • 1970-01-01
    • 2018-10-24
    • 1970-01-01
    • 2014-05-26
    • 2019-06-04
    • 1970-01-01
    相关资源
    最近更新 更多