Scala Play Future [回复]总是空着

时间:2016-02-01 03:28:58

标签: scala playframework playframework-2.0 future

Future[Response].valueOption[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
  }

1 个答案:

答案 0 :(得分:2)

Future#value不会阻碍未来。如果在致电value时已完成未来,您将获得Some(_),否则将获得None。因此,您只看到None,因为您在发送请求后立即检查了value,但尚未完成。您可以使用collectrecoverWith等未来的组合器来实现重试功能,并返回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)
  }