Future[Response].value
:Option[Try[Response]]
始终为空。我是否误解了期货?我需要将其包裹在onSuccess
中吗?但是它不会返回一个String,而是一个Unit?
@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
}
答案 0 :(得分: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)
}