Scala 在单打动作中进行独立的流畅查询
我有一个async PlayScala 在单打动作中进行独立的流畅查询,scala,playframework,slick,slick-3.0,Scala,Playframework,Slick,Slick 3.0,我有一个async PlayAction,它使用Slick从数据库检索数据。显然,Slick使用Futures来避免阻塞: def show(id: Long) = Action.async { db.run(entities.filter(_.id === id).result.headOption).map { case None => templateFor("NEW_OBJECT") case Some(x) => Ok(x) } def templateFo
Action
,它使用Slick从数据库检索数据。显然,Slick使用Future
s来避免阻塞:
def show(id: Long) = Action.async {
db.run(entities.filter(_.id === id).result.headOption).map {
case None => templateFor("NEW_OBJECT")
case Some(x) => Ok(x)
}
def templateFor(code: String): Future[Result] = {
db.run(templates.filter(_.code === code).result.headOption).map {
case None => InternalServerError("No template")
case Some(x) => Ok(x)
}
}
问题是调用
templateFor()
返回Future
,因此整个操作
返回Future[Future[Result]]
,这不是游戏所期望的。因此,我想摆脱嵌套的未来。最简单的方法是等待它的完成,但我希望避免不必要的阻塞。如果我能够使用templateFor()
函数生成的Future[Result]
并从我的操作中完整地返回它,从而用它替换外部的Future
,那就太好了。你可以使用flatMap
对于任何单体结构,如Future[T]
,flatMap
采用类型为T=>SomeOtherMonad[K]
的函数,如果是单体,则将该函数应用于所有元素,然后将其展平,以提供Future[K]
def show(id: Long) = Action.async {
db.run(entities.filter(_.id === id).result.headOption).flatMap {
case None => templateFor("NEW_OBJECT")
case Some(x) => Future(Ok(x))
}
def templateFor(code: String): Future[Result] =
db.run(templates.filter(_.code === code).result.headOption).map {
case None => InternalServerError("No template")
case Some(x) => Ok(x)
}
}
您可以使用flatMap
进行此操作
对于任何单体结构,如Future[T]
,flatMap
采用类型为T=>SomeOtherMonad[K]
的函数,如果是单体,则将该函数应用于所有元素,然后将其展平,以提供Future[K]
def show(id: Long) = Action.async {
db.run(entities.filter(_.id === id).result.headOption).flatMap {
case None => templateFor("NEW_OBJECT")
case Some(x) => Future(Ok(x))
}
def templateFor(code: String): Future[Result] =
db.run(templates.filter(_.code === code).result.headOption).map {
case None => InternalServerError("No template")
case Some(x) => Ok(x)
}
}
flatMap
it:)正如@ipoteka所说:)flatMap
it:)正如@ipoteka所说:)