使用 Scala 和 Play 异步计算 Future Boolean
Evaluating a Future Boolean asynchronously using Scala and Play
我有一个 returns 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)))
}
但我不认为我想要 Await 在那里。所以我正在尝试这样的事情但没有成功:
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()
已经 returns。您所要做的就是 map
得到适当的结果。
使用 Futures
时,您必须使用 map
和 flatMap
等组合子来表达最终值。例如:
Action.async {
healthCheckService.checkDynamo()
.map { result => // boolean
HealthCheckResponse(result.toString)
}
.map(Json.toJson(_))
.map(Ok(_))
}
(您可以将上面的 map
合并到一个 map
并在那里构建最终的 Ok
值;这或多或少是一个品味问题)
例如,如果您有两个要执行的异步调用并且 return 基于它们的结果的结果,您可以使用 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
我有一个 returns 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)))
}
但我不认为我想要 Await 在那里。所以我正在尝试这样的事情但没有成功:
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()
已经 returns。您所要做的就是 map
得到适当的结果。
使用 Futures
时,您必须使用 map
和 flatMap
等组合子来表达最终值。例如:
Action.async {
healthCheckService.checkDynamo()
.map { result => // boolean
HealthCheckResponse(result.toString)
}
.map(Json.toJson(_))
.map(Ok(_))
}
(您可以将上面的 map
合并到一个 map
并在那里构建最终的 Ok
值;这或多或少是一个品味问题)
例如,如果您有两个要执行的异步调用并且 return 基于它们的结果的结果,您可以使用 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