Play 2.2 -Scala - How to chain Futures in Controller Action

前端 未结 2 1590
不知归路
不知归路 2021-02-06 12:51

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.

Pseudo

相关标签:
2条回答
  • 2021-02-06 13:33

    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))
        }
    
    0 讨论(0)
  • 2021-02-06 13:47

    I found this solution but I dont think that it is a good solution because Iam using Await.result() which is a blocking operation. If anyone knows how to refactor this code without blocking operations please let me know.

    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") }
      }
    }
    
    0 讨论(0)
提交回复
热议问题