scala: последовательность выполнения действий контроллера playframework с будущим - PullRequest
0 голосов
/ 15 мая 2018

У меня проблема с моим сервером Play-Framework API.Мне нужно иметь некоторую обработку, выполняющуюся в фоновом режиме, которая возвращает Future с результатом, а затем записывает результат как ответ.Тем не менее, поток запросов полностью завершается и возвращается до завершения моего будущего.Вот код ...

 def requestAction(): Action[AnyContent] = Action.async { implicit request =>
    var fResult: Future[String] = Future { "initial value" }
    try {
       fResult = doSomethingAsyncAndGetResponseString(); // return "great, everything is done"
    }
    catch {
       case t: Throwable {
           fResult = Future { "failed" }
       }
    }
    // done, return response, but the problem is, this is executed first because doSomethingAsyncAndGetResponseString() is still executing and returns later
    fResult.map( res => {
        // problem here, because I get "initial value" which is not what I want
        Ok(res)
    }
}

Есть ли способ получить "отлично, все сделано" или "не удалось" без Async.await?Я использовал этот формат на своем сервере API, но сегодня он сломался, потому что в новом API, который я пишу, doSomethingAsyncAndGetResponseString немного длиннее.Я этого не ожидал, поэтому что-то не так с моим пониманием структуры.

Заранее спасибо!

1 Ответ

0 голосов
/ 15 мая 2018

Вы пытаетесь написать Java код, используя Scala.

Вы делаете это неправильно. Прочитайте о Future с и как их использовать.

Вот учебник

Future s может быть составлен с использованием конструкций map и flatMap. recover и recoverWith предоставят пользователю доступ к исключению, произошедшему в конвейере вычислений

Вы должны сделать что-то вроде этого, приведенное ниже

def requestAction(): Action[AnyContent] = Action.async { implicit request =>
    Future { "initial value" }.flatMap { _ =>
      doSomethingAsyncAndGetResponseString() // returns Future
    }.map { res =>
      Ok(res)
    }.recover { case th =>
      Ok(th.getMessage)
    }
}

Обработка исключений и восстановление после исключений

Обработка исключений встроена в Future.

recover предоставляет доступ к исключению, а также помогает пользователю предоставить альтернативное значение успеха в случае исключения.

recoverWith предоставляет доступ к исключению, а также помогает пользователю предоставить / цепочку альтернативных Future вычислений, которые могут быть успешными или неудачными.

Future {
 throw new Exception("foo exception")
}.recover {
  case th => println(s"msg: ${th.getMessage}")
}
...