使用Scala和Play异步评估Future布尔值

问题描述 投票:0回答:2

我有一个方法,在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"))
        }

      }
    }

我甚至无法编译那些来测试它们。有什么建议?

scala playframework
2个回答
2
投票

试试这个:

def health = Action.async {
  healthCheckService.checkDynamo().map {
    case true => Ok(Json.toJson("false"))
    case false => Ok(Json.toJson("true"))
  }
}

让Play在引擎盖下处理等待你。也就是说,Action.async接受了FuturecheckDynamo()已经回归。所有你需要做的是map它到适当的结果。


2
投票

使用Futures,你必须使用像mapflatMap这样的组合来表达最终值。例如:

Action.async {
  healthCheckService.checkDynamo()
    .map { result =>  // boolean
      HealthCheckResponse(result.toString)
    }
    .map(Json.toJson(_))
    .map(Ok(_))
}

(您可以将上面的maps合并到一个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

© www.soinside.com 2019 - 2024. All rights reserved.