Play 2.2 -Scala - 如何在控制器动作中链接期货 [英] Play 2.2 -Scala - How to chain Futures in Controller Action
问题描述
我有 3 个 Response 类型的期货.第一个 future 返回一个 JsValue,它定义了是执行 future 2 和 future 3 还是只执行 future 3.
I have 3 futures of type Response. The first future returns a JsValue which defines if future 2 and future 3 shall be executed or only future 3 shall be executed.
伪代码:如果 Future 1 那么 {future2 and future 3}否则未来3
Pseudocode: If Future 1 then {future2 and future 3} else future 3
我正在尝试在 play 框架操作中执行此操作,这意味着为了以后使用期货的结果,我不能使用 onSuccess、onFailure 和 onComplete,因为它们都返回 Unit 而不是上次期货的实际 JsValue.
Iam trying to do this in a play framwork action which means in order to use the result of the futures later I cant use onSuccess, onFailure and onComplete because all of them return Unit and not the actual JsValue from the last future.
我尝试使用 map() 和 andThen 来做到这一点,但我是 Scala 菜鸟,我想我无法做到,因为我总是错过了一点点.这是我目前行不通的方法!
I tried to do this with map() and andThen but I am a Scala noob and I guess i wasn't able to do it because I always just missed a little point. Here is my current approach which does not work!
def addSuggestion(indexName: String, suggestion: String) = Action.async {
val indexExistsQuery: IndexExistsQuery = new IndexExistsQuery(indexName);
val addSuggestionQuery: AddSuggestionQuery = new AddSuggestionQuery(indexName, suggestion)
val indexCreationQuery: CreateCompletionsFieldQuery = new CreateCompletionsFieldQuery(indexName)
val futureResponse: Future[Response] = for {
responseOne <- EsClient.execute(indexExistsQuery)
responseTwo <- EsClient.execute(indexCreationQuery) if (indexExistsQuery.getBooleanResult(indexExistsQuery.getResult(responseOne)))
responseThree <- EsClient.execute(addSuggestionQuery)
} yield responseThree
futureResponse.map { response =>
Ok("Feed title: " + (response.json))
}
推荐答案
我创建了一些伪代码:
checkIndexExists() map {
case true => Future.successful()
case false => createIndex()
} flatMap { _ =>
query()
}.map { response =>
Ok("Feed title: " + (response.json))
}.recover {
case _ => Ok("bla")
}
首先,如果索引存在,则启动查询.然后,如果成功,您可以映射该未来如何使用该 Future[Boolean]
.由于您使用地图,因此您可以提取Boolean
.如果索引存在,您只需创建一个已经完成的未来.如果索引不存在,您需要启动索引创建命令.现在你的情况是你嵌套了 Future
的 (Future[Future[Response]]
).使用 flatMap
删除一维,这样你就只有 Future[Response]
.这可以映射到播放结果.
First you fire up the query if the index exists.
Then you map that future how to work with that Future[Boolean]
if it successful. Since you use map, you kind of extract the Boolean
. If the index exists, you just create a future that is already complete. If the index not exists you need to fire up the index creation command. Now you have the situation that you have nested Future
's (Future[Future[Response]]
). Using flatMap
you remove one dimension, so that you only have Future[Response]
. That can be mapped to a Play result.
更新(MeiSign的实现):
Update (the implementation of MeiSign):
EsClient.execute(indexExistsQuery) map { response =>
if (indexExistsQuery.getBooleanResult(indexExistsQuery.getResult(response))) Future.successful(Response)
else EsClient.execute(indexCreationQuery)
} flatMap { _ =>
EsClient.execute(addSuggestionQuery)
} map { response: Response =>
Ok("Feed title: " + (response.json))
}
这篇关于Play 2.2 -Scala - 如何在控制器动作中链接期货的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!