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 但它还没有完成。您可以使用 collectrecoverWith 等未来的组合器来实现重试功能,并且 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)
  }