在我的后端控制器功能中,我有以下代码:
def getContentComponents = Action.async {
contentComponentDTO.list().map { contentComponentsFuture =>
contentComponentsFuture.foreach(contentComponentFuture =>
contentComponentFuture.typeOf match {
case 5 => contentComponentDTO.getContentComponentText(contentComponentFuture.id.get).map(text => {
contentComponentFuture.text = text.text
println(contentComponentFuture.text)
})
}
)
Ok(Json.toJson(contentComponentsFuture))
}
}
问题是,在上述内容完成之前调用了OK()
。是否有一种聪明的方式可以等到foreach
完成?
感谢
这是两个有不同问题的不同问题!这就是两个问题看起来相似的原因
答案 0 :(得分:0)
您可以采取两种方法,但在此之前,让我们回顾一下您要做的事情。
现在你的contentComponentsFuture是一个可变变量(我强烈建议不要使用,坚持不可变数据)有一个你需要更新的文本字段。 现在Ok()之前的所有代码块将返回未来,因为它正在处理未来的列表。因此,最简单的解决方案是在未来绘制地图并返回结果。未来的地图只是一个onComplete函数,一旦未来得到解决就会触发。所以代码看起来像:
def getContentComponents = Action.async {
val futureResult = contentComponentDTO.list().map { contentComponentsFuture =>
contentComponentsFuture.map(contentComponentFuture =>
contentComponentFuture.typeOf match {
case 5 => contentComponentDTO.getContentComponentText(contentComponentFuture.id.get).map(text => {
contentComponentFuture.text = text.text
contentComponentFuture
})
}
)
}
futureResult.map(result => {
Future.sequence(result).map(t => Ok(Json.toJson(t))
})) }
另一个选项是使用scala asycn库:https://github.com/scala/scala-async 它提供了一个方便的包装器,因此您不需要显式地映射未来,上面与scala异步库相同的代码将如下所示:
def getContentComponents = Action.async {
Async.async {
val result = Async.await(contentComponentDTO.list().map { contentComponentsFuture =>
contentComponentsFuture.map(contentComponentFuture =>
contentComponentFuture.typeOf match {
case 5 => contentComponentDTO.getContentComponentText(contentComponentFuture.id.get).map(text => {
contentComponentFuture.text = text.text
contentComponentFuture
})
}
)
})
Ok(Json.toJson(result))
}
}