异步行动和未来

时间:2016-05-24 12:00:33

标签: scala asynchronous playframework

我使用Play 2.5和Scala 2.11。我尝试使用带有Future的异步Action来返回json字符串,但无法使其工作。 这是我的行动:

def getData = Action.async { implicit request =>
    val futureData = Future { daoObj.fetchData }
    futureData onComplete {
        case Success(data) =>
            Ok(Json.prettyPrint(Json.obj("data" -> data.groupBy(_.name))))
        case Failure(t) => 
            BadRequest(Json.prettyPrint(Json.obj(
                "status" -> "400",
                "message" -> s"$t"
            )))
    }
}

daoObj.fetchData返回scala.concurrent.Future [List [models.Data]]

这是models.Data:

case class Data(name: String, details: String)

我可以拥有这样的数据

Data (name = "data1", details = "details1")
Data (name = "data1", details = "details1a")
Data (name = "data2", details = "details2")

我可以加入名称以返回表格

的结构
Map(data1 -> List("details1", "details11"),
    data2 -> List("details2"))

我在groupBy上有编译错误:

value groupBy is not a member of scala.concurrent.Future[List[models.Data]]

1)如何在我的行动中从未来获得价值(List [models.Data])?

2)这是我的第一个Play Scala应用,所以如果您有任何评论可以改进我的代码,那么欢迎您。

1 个答案:

答案 0 :(得分:1)

您不应该使用Future.onComplete,这是一个回调(带有副作用),但.map.recover会将您的Future[T]变为Future[Result]这是Action.async所期望的。

def getData = Action.async { implicit request =>
  Future { daoObj.fetchData }.map { data =>
    Json.obj("data" -> data.groupBy(_.name))
  }.recover {
    case error => BadRequest(Json.obj(
      "status" -> "400",
      "message" -> error.getMessage
    ))
  }
}
  

没有必要打印JsObject可以直接写成的结果(除了调试目的)。