5

タイプ Response の先物が 3 つあります。最初のフューチャーは、フューチャー 2 とフューチャー 3 を実行するか、フューチャー 3 のみを実行するかを定義する JsValue を返します。

擬似コード: もし未来 1 なら {未来 2 と未来 3} でなければ未来 3

つまり、後で先物の結果を使用するために、onSuccess、onFailure、および onComplete を使用できません。これらはすべて、最後の未来からの実際の JsValue ではなく Unit を返すためです。

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))
}
4

2 に答える 2

3

私はいくつかの擬似コードを作成しました:

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すると、1 つの次元が削除されるため、 のみになりますFuture[Response]。これは Play の結果にマッピングできます。

更新 (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))
    }
于 2013-10-23T20:55:14.120 に答える
0

私はこの解決策を見つけましたが、ブロック操作である Await.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") }
  }
}
于 2013-10-23T20:52:23.933 に答える