我有一个方法,在Play控制器中返回Future [Boolean],我想用异步来评估它,但我似乎无法编译它。以下将有效:
def health = Action {
logger.info("Endpoint method: health")
val isHealthy = healthCheckService.checkDynamo()
val b: Boolean = Await.result(isHealthy, scala.concurrent.duration.Duration(5, "seconds"))
Ok(Json.toJson(HealthCheckResponse(b.toString)))
}
但我不认为我想在那里等待。所以我尝试这样的事情没有成功:
def health =
Action.async {
Future {
logger.info("Endpoint method: health")
healthCheckService.checkDynamo() match {
case Future.successful(true) => Ok(Json.toJson("false"))
case false => Ok(Json.toJson("true"))
}
val r = healthCheckService.checkDynamo() match {
case true => Ok(Json.toJson("false"))
case false => Ok(Json.toJson("true"))
}
}
}
我甚至无法编译那些来测试它们。有什么建议?
试试这个:
def health = Action.async {
healthCheckService.checkDynamo().map {
case true => Ok(Json.toJson("false"))
case false => Ok(Json.toJson("true"))
}
}
让Play在引擎盖下处理等待你。也就是说,Action.async
接受了Future
,checkDynamo()
已经回归。所有你需要做的是map
它到适当的结果。
使用Futures
,你必须使用像map
和flatMap
这样的组合来表达最终值。例如:
Action.async {
healthCheckService.checkDynamo()
.map { result => // boolean
HealthCheckResponse(result.toString)
}
.map(Json.toJson(_))
.map(Ok(_))
}
(您可以将上面的map
s合并到一个map
并在那里构建最终的Ok
值;它或多或少是品味问题)
如果您有两个要执行的异步调用并根据结果返回结果,则可以使用flatMap
,这可以使用for
理解来轻松表达:
Action.async {
for {
result1 <- someService.someCall()
result2 <- anotherService.anotherCall(result1.someProperty)
finalResult = SomeFinalResultType(result1, result2)
} yield Ok(Json.toJson(finalResult))
}
如果您不熟悉期货,您可能需要阅读一些解释其性质的教程,如何将它们组合以及如何从中获得有用的结果,如下所示:http://hello-scala.com/920-scala-futures.html