播放2.2 -Scala-如何在控制器操作中链接期货 [英] Play 2.2 -Scala - How to chain Futures in Controller Action
问题描述
我有3个类型为Response的期货.第一个Future返回一个JsValue,它定义是执行Future 2和Future 3还是仅执行Future 3.
伪代码: 如果是Future 1,则{future2 and future 3} 否则未来3
我正在尝试通过播放框架动作来执行此操作,这意味着为了以后使用期货的结果,我不能使用onSuccess,onFailure和onComplete,因为它们全部返回Unit,而不是最后一个期货的实际JsValue. /p>
我试图用map()和andThen来做到这一点,但是我是Scala菜鸟,我想我做不到,因为我总是只漏了一点.这是我目前无法使用的方法!
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]
.可以将其映射到播放结果.
更新(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))
}
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.
Pseudocode: If Future 1 then {future2 and future 3} else future 3
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.
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))
}
I created some pseudocode:
checkIndexExists() map {
case true => Future.successful()
case false => createIndex()
} flatMap { _ =>
query()
}.map { response =>
Ok("Feed title: " + (response.json))
}.recover {
case _ => Ok("bla")
}
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.
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))
}
这篇关于播放2.2 -Scala-如何在控制器操作中链接期货的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!