【发布时间】:2018-07-01 17:43:45
【问题描述】:
在我的 Play 网络应用程序中,我使用 val resultRack = Await.result(futureList, Duration.Inf) 从 Future 获取结果。是否有另一种更好的方法(使用最佳实践)从数据库中获取结果?如果我使用onComplete 或onSuccess,我的控制器将完成执行,结果还没有在val 中。下面是我的Controller方法。一切正常,但我需要遵循 Scala 中的更多最佳实践。
已编辑:我已经在其他方法上使用Action.async。但是在这个我不能使用,主要是因为either.fold。我想我需要一个 map 包围该方法的所有代码,然后才能验证 json。
def addRack = Action(parse.json) { request =>
val either = request.body.validate[Rack]
either.fold(
errors => BadRequest("invalid json Rack.\n"),
rack => {
val f: Future[Option[RackRow]] = rackRepository.getById(rack.id)
val result = Await.result(f, Duration.Inf)
result match {
case Some(r) =>
// If the Rack already exists we update the produced and currentTime properties
val fGpu: Future[Seq[GpuRow]] = gpuRepository.getByRack(r.id)
// val total = fGpu.map(_.map(_.produced).sum)
val resultGpu = Await.result(fGpu, Duration.Inf)
val total = resultGpu.map(_.produced).sum
rackRepository.update(r.id, Some(total), Some(System.currentTimeMillis))
Ok("Rack already exists! Updated produced and currentTime.\n")
case None =>
// If the Rack does not exist we create it.
val rackRow = RackRow(rack.id, rack.produced, System.currentTimeMillis)
rackRepository.insert(rackRow)
Ok
}
}
)
}
新方法使用 flatMap 和地图。我的问题是我正在控制器内创建和填充 seq rackSeq。我用来创建这个对象的gpuSeq 没有被评估,因为它来自未来。我应该如何评估这个未来gpuSeq?在我的结果中,我只能看到rackSeq,但gpuSeq 的列表始终为空。
此外,如果代码 Util.toTime(at) 抛出错误,我无法使用 recover 捕获此错误。据我了解,我可以这样做....
def getRacks(at: String) = Action.async { implicit request: Request[AnyContent] =>
var rackSeq: Seq[Rack] = Seq.empty
var gpuSeq: Seq[Gpu] = Seq.empty
rackRepository.get(Util.toTime(at)).flatMap { resultRack: Seq[RackRow] =>
resultRack.map { r: RackRow =>
gpuRepository.getByRack(r.id).map { result: Seq[GpuRow] =>
result.map { gpuRow: GpuRow =>
gpuSeq = gpuSeq :+ Gpu(gpuRow.id, gpuRow.rackId, gpuRow.produced, Util.toDate(gpuRow.installedAt))
println(gpuRow)
}
}
val rack = Rack(r.id, r.produced, Util.toDate(r.currentHour), gpuSeq)
rackSeq = rackSeq :+ rack
}
// val result = Await.result(listGpu, Duration.Inf)
// result.foreach { gpuRow =>
// gpuSeq = gpuSeq :+ Gpu(gpuRow.id, gpuRow.rackId, gpuRow.produced, Util.toDate(gpuRow.installedAt))
// }
Future.successful(Ok(Json.toJson(rackSeq)).as(JSON))
}.recover {
case pe: ParseException => BadRequest(Json.toJson("Error on parse String to time."))
case e: Exception => BadRequest(Json.toJson("Error to get racks."))
case _ => BadRequest(Json.toJson("Unknow error to get racks."))
}
}
【问题讨论】:
-
引用this 在类似情况下帮助了我很多
标签: scala playframework future