重头戏2.2-Scala-如何在控制器操作中连锁期货

重头戏2.2-Scala-如何在控制器操作中连锁期货,scala,playframework,future,playframework-2.2,Scala,Playframework,Future,Playframework 2.2,我有3种类型的未来反应。第一个future返回一个JsValue,该值定义是执行future 2和future 3,还是只执行future 3 伪代码: 如果未来1,则{future2和future3} 其他未来3 我试图在一个游戏框架动作中做到这一点,这意味着为了以后使用未来的结果,我不能使用onSuccess、onFailure和onComplete,因为它们都返回单位,而不是上一个未来的实际JS值 我试着用map()来做这件事,但我是一个Scala noob,我想我做不到,因为我总是错过一

我有3种类型的未来反应。第一个future返回一个JsValue,该值定义是执行future 2和future 3,还是只执行future 3

伪代码: 如果未来1,则{future2和future3} 其他未来3

我试图在一个游戏框架动作中做到这一点,这意味着为了以后使用未来的结果,我不能使用onSuccess、onFailure和onComplete,因为它们都返回单位,而不是上一个未来的实际JS值

我试着用map()来做这件事,但我是一个Scala noob,我想我做不到,因为我总是错过一点。这是我目前的方法,它不起作用

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))
}
def addSuggestion(indexName:String,suggestion:String)=Action.async{
val indexExistsQuery:indexExistsQuery=新indexExistsQuery(indexName);
val addSuggestionQuery:addSuggestionQuery=新建addSuggestionQuery(索引名,建议)
val indexCreationQuery:CreateCompletionsFieldQuery=新建CreateCompletionsFieldQuery(indexName)
val futureResponse:Future[Response]=for{

responseOne我找到了这个解决方案,但我认为它不是一个好的解决方案,因为我使用的是wait.result()这是一个阻塞操作。 如果有人知道如何在不阻塞操作的情况下重构此代码,请告诉我

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 indexExists: Boolean = indexExistsQuery.getBooleanResult(indexExistsQuery.getResult(Await.result(EsClient.execute(indexExistsQuery), 5.second)))
  if (indexExists) {
    EsClient.execute(addSuggestionQuery).map { response => Ok("Feed title: " + (response.json)) }
  } else {
    val futureResponse: Future[Response] = for {
      responseTwo <- EsClient.execute(indexCreationQuery)
      responseThree <- EsClient.execute(addSuggestionQuery)
    } yield responseThree

    futureResponse.map { response =>
      {
        Ok("Feed title: " + (response.json))
      }
    }.recover { case _ => Ok("bla") }
  }
}
def addSuggestion(indexName:String,suggestion:String)=Action.async{
val indexExistsQuery:indexExistsQuery=新indexExistsQuery(indexName);
val addSuggestionQuery:addSuggestionQuery=新建addSuggestionQuery(索引名,建议)
val indexCreationQuery:CreateCompletionsFieldQuery=新建CreateCompletionsFieldQuery(indexName)
val indexExists:Boolean=indexistskery.getbooleansresult(indexistskery.getResult(wait.result(EsClient.execute(indexistskery),5.second)))
if(indexists){
execute(addSuggestionQuery).map{response=>Ok(“提要标题:”+(response.json))}
}否则{
val futureResponse:Future[Response]=for{
响应Ok(“bla”)}
}
}

我创建了一些伪代码:

checkIndexExists() map {
  case true => Future.successful()
  case false => createIndex()
} flatMap { _ =>
  query()
}.map { response =>
  Ok("Feed title: " + (response.json))
}.recover { 
  case _ => Ok("bla") 
} 
首先,如果索引存在,则启动查询。 然后映射未来如何使用
future[Boolean]
如果成功。由于您使用map,您可以提取
布尔值
。如果索引存在,您只需创建一个已经完成的未来。如果索引不存在,您需要启动索引创建命令。现在您已经嵌套了
future
future[future[Response]]
)。使用
flatMap
可以删除一个维度,这样您就只有
Future[Response]
。可以映射到播放结果

更新(Mesign的实施):


这里是实现的解决方案,非常感谢:为什么要在运行时创建索引?不应该提前完成吗?在我的用例中,索引有一个固定的映射,我希望能够在运行时创建它们。我们在这里讨论的是可以视为内容容器的elasticsearch索引。
  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))
    }