2016-02-01 3 views
0

Future[Response].value: Option[Try[Response]] всегда пуст. Я не понимаю фьючерсов? Нужно ли обертывать это в onSuccess? Но тогда он не вернет String, а Unit?Scala Play Future [Response] всегда пуст

@tailrec private def initConnection: String = 
    { 
    val response: Future[Response] = initHeaders(WS.url(url)).post(authBody) 
    val retry: Boolean = { 
     response.value.isEmpty || response.value.get.isFailure || response.value.get.get.header("ConnectionID").isEmpty 
    } 

    if (!retry) return response.value.get.get.header("ConnectionID").get 
    else initConnection 
    } 

ответ

2

Future#value не блокирует будущее. Если будущее уже завершено во время звонка value, вы получите Some(_), в противном случае это будет None. Таким образом, вы видите только None, так как вы проверяете value сразу же после отправки запроса, и он еще не закончен. Вы можете использовать будущие комбинаторы, такие как collect и recoverWith, чтобы реализовать функцию повтора и вернуть Future[String] вместо String. Если вам действительно нужно значение позже, вам нужно будет Await.result будущее.

import scala.util.control.NonFatal 
import scala.concurrent.Await 

private def initConnectionFuture: Future[String] = 
    initHeaders(WS.url(url)).post(authBody).collect { 
    case response if response.header("ConnectionID").isDefined => 
     response.header("ConnectionID").get 
    }.recoverWith { 
    case NonFatal(_) => initConnectionFuture 
    } 

private def initConnection: String = 
    Await.result(initConnectionFuture, 5 seconds) // or any other acceptable timeout 

В дополнение к таймауту вы также можете ограничить количество попыток, например.

private def initConnectionFuture(retries: Int = 5): Future[String] = 
    initHeaders(WS.url(url)).post(authBody).collect { 
    case response if response.header("ConnectionID").isDefined => 
     response.header("ConnectionID").get 
    }.recoverWith { 
    case NonFatal(_) if retries > 0 => initConnectionFuture(retries - 1) 
    } 
+0

Спасибо, я думал, что будет выполняться асинхронно до тех пор, пока значение не понадобится, и в этот момент оно будет автоматически блокироваться. – kliew

+0

Правильно ли следующее утверждение? «Оптимизация параллелизма, выполняемая в будущем, выполняется во время компиляции. Мое предыдущее предположение потребовало бы оптимизации во время выполнения». – kliew

+0

По дизайну, ни один метод на Будущее никогда не будет блокироваться. Единственный вызов, который блокирует, - 'Await.result', и это не определено в Future. – knutwalker

Смежные вопросы