Scala Play:如何等到将来完成,然后再将OK结果返回到前端 [英] Scala Play: how to wait until future is complete before OK result is returned to frontend
问题描述
在我的playframework应用程序中,我想等到我的未来完成并返回到视图中.
In my playframework application I want to wait until my future is completed and the return it to the view.
我的代码如下:
def getContentComponentUsageSearch: Action[AnyContent] = Action.async { implicit request =>
println(request.body.asJson)
request.body.asJson.map(_.validate[StepIds] match {
case JsSuccess(stepIds, _) =>
println("VALIDE SUCCESS -------------------------------")
val fList: List[Seq[Future[ProcessTemplatesModel]]] = List() :+ stepIds.s.map(s => {
processTemplateDTO.getProcessStepTemplate(s.processStep_id).flatMap(stepTemplate => {
processTemplateDTO.getProcessTemplate(stepTemplate.get.processTemplate_id.get).map(a => {
a.get
})
})
})
fList.map(u => {
val a: Seq[Future[ProcessTemplatesModel]] = u
Future.sequence(a).map(s => {
println(s)
})
})
Future.successful(Ok(Json.obj("id" -> "")))
case JsError(_) =>
println("NOT VALID -------------------------------")
Future.successful(BadRequest("Process Template not create client"))
case _ => Future.successful(BadRequest("Process Template create client"))
}).getOrElse(Future.successful(BadRequest("Process Template create client")))
}
pirntln(s)
正在打印完成的东西.但是如何等待它完成,然后将其返回视图?
the pirntln(s)
is printing the finished stuff. But how can I wait until it is complete and return it then to the view?
预先感谢
更新:
也尝试过这个:
val process = for {
fList: List[Seq[Future[ProcessTemplatesModel]]] <- List() :+ stepIds.s.map(s => {
processTemplateDTO.getProcessStepTemplate(s.processStep_id).flatMap(stepTemplate => {
processTemplateDTO.getProcessTemplate(stepTemplate.get.processTemplate_id.get).map(a => {
a.get
})
})
})
} yield (fList)
process.map({ case (fList) =>
Ok(Json.obj(
"processTemplate" -> fList
))
})
但后来我明白了:
更新: 我的问题是fList中的期货在返回OK结果之前没有完成
UPDATE: My problem is that the futures in fList do not complete before an OK result is returned
推荐答案
问题中的代码似乎不可编译,因此这是未经测试的非常粗略的草图,希望可以为进一步搜索正确的解决方案提供足够的启发:
The code in the question didn't seem compilable, so here is an untested very rough sketch, that hopefully provides enough inspiration for further search of the correct solution:
def getContentComponentUsageSearch: = Action.async { implicit req =>
req.body.asJson.map(_.validate[StepIds] match {
case JsSuccess(stepIds, _) => {
// Create list of futures
val listFuts: List[Future[ProcessTemplatesModel]] = (stepIds.s.map(s => {
processTemplateDTO.
getProcessStepTemplate(s.processStep_id).
flatMap{ stepTemplate =>
processTemplateDTO.
getProcessTemplate(stepTemplate.get.processTemplate_id.get).
map(_.get)
}
})).toList
// Sequence all the futures into a single future of list
val futList = Future.sequence(listFuts)
// Flat map this single future to the OK result
for {
listPTMs <- futList
} yield {
// Apparently some debug output?
listPTMs foreach printl
Ok(Json.obj("id" -> ""))
}
}
case JsError(_) => {
println("NOT VALID -------------------------------")
Future.successful(BadRequest("Process Template not create client"))
}
case _ => Future.successful(BadRequest("Process Template create client"))
}).getOrElse(Future.successful(BadRequest("Process Template create client")))
}
如果我正确理解了您的问题,那么您要确保在返回确定之前,确保列表中的所有期货均已完成.因此,我首先创建了List[Future[...]]
:
If I understood your question correctly, what you wanted was to make sure that all futures in the list complete before you return the OK. Therefore I have first created a List[Future[...]]
:
val listFuts: List[Future[ProcessTemplatesModel]] = // ...
然后,我将所有期货合并到一个列表的期货中,该清单仅在每个元素都已完成时才完成:
Then I've combined all the futures into a single future of list, which completes only when every element has completed:
// Sequence all the futures into a single future of list
val futList = Future.sequence(listFuts)
然后,我使用for
-comprehension来确保listPTMs
在返回OK
之前完成计算:
Then I've used a for
-comprehension to make sure that the listPTMs
finishes computation before the OK
is returned:
// Flat map this single future to the OK result
for {
listPTMs <- futList
} yield {
// Apparently some debug output?
listPTMs foreach printl
Ok(Json.obj("id" -> ""))
}
for-yield
(在此等同于map
)是建立完成行为的先决条件,以便在构造OK
之前对listPTMs
进行全面评估.
The for-yield
(equivalent to map
here) is what establishes the finish-this-before-doing-that behavior, so that listPTMs
is fully evaluated before OK
is constructed.
这篇关于Scala Play:如何等到将来完成,然后再将OK结果返回到前端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!