在 Future 使用 Play2 完成后渲染页面

rendering a page after Future is done with Play2

使用带有 Slick DB 管理器的 Play2 框架,我有一个 class 封装了 DB 访问,以及一个负责将该信息返回给用户的控制器。大致有这样的:

Class 具有数据库访问权限:

  override def getAllAnswersFuture(userID: Int): Future[List[UserAnswer]] = {
    (DB QUERY CREATION AS allAnswersQuery)
    val myquery : Future[Seq[(Int, String)]] =myDB.run(allAnswersQuery.result)

    myquery.map{x => x.map(elem =>(
      UserAnswer(elem._1, elem._2).toList}
  }

控制器:

  def index = Action { request =>
    request.session.get("userID").map { userID =>
      val myUser = userStorage.getUser(userID.toInt)
      val allAnswersFuture  = questionStorage.getAllAnswersFuture(myUser.id)
      allAnswersFuture onComplete {case _ => Ok(views.html.app.stats())}
      Ok(views.html.app.index("Future did not work"))
    }.getOrElse {
      Unauthorized("Oops, you are not connected")
    }
  }

出于某种原因,onComplete 的内容从未显示,而是返回 "future did not work"。

我的问题是,如何让 Play2 等到数据库查询完成后再打印结果?

使用 Action.async 处理期货并尝试做类似的事情:

def index = Action.async { request =>
    allAnswersFuture.map{_ => Ok(views.html.app.stats())}.recover {
   case ex: Exception =>
      Ok(views.html.app.index("Future did not work"))
 }
}

如果您想 return 将来回调时使用 Map 和恢复,而不是在将来使用 onComplete。 Future 上的 OnComplete 不会 return 任何东西,它的 return 类型是 Unit。 如果 Future 成功,您的统计信息页面将被填充,失败时索引页面将从恢复块中填充。

并在您的 getOrElse 块中使用:

Future.successful(Unauthorized("Oops, you are not connected"))

这就足够了