Scala Play Future[响应]总是空的
Scala Play Future[Response] always empty
Future[Response].value
: Option[Try[Response]]
总是空的。我误解期货了吗?我需要用 onSuccess
包装它吗?但是它不会 return 一个字符串,而是一个单位?
@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
}
Future#value
不会阻止未来。如果在调用 value
时 future 已经完成,你将得到 Some(_)
,否则将是 None
。所以你只看到 None
因为你在发送请求后立即检查了 value
但它还没有完成。您可以使用 collect
和 recoverWith
等未来的组合器来实现重试功能,并且 return 是 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)
}
Future[Response].value
: Option[Try[Response]]
总是空的。我误解期货了吗?我需要用 onSuccess
包装它吗?但是它不会 return 一个字符串,而是一个单位?
@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
}
Future#value
不会阻止未来。如果在调用 value
时 future 已经完成,你将得到 Some(_)
,否则将是 None
。所以你只看到 None
因为你在发送请求后立即检查了 value
但它还没有完成。您可以使用 collect
和 recoverWith
等未来的组合器来实现重试功能,并且 return 是 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)
}