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)
}
Спасибо, я думал, что будет выполняться асинхронно до тех пор, пока значение не понадобится, и в этот момент оно будет автоматически блокироваться. – kliew
Правильно ли следующее утверждение? «Оптимизация параллелизма, выполняемая в будущем, выполняется во время компиляции. Мое предыдущее предположение потребовало бы оптимизации во время выполнения». – kliew
По дизайну, ни один метод на Будущее никогда не будет блокироваться. Единственный вызов, который блокирует, - 'Await.result', и это не определено в Future. – knutwalker