Scala Play框架期货

时间:2018-11-08 00:55:30

标签: scala playframework future

我有3种方法:a,b和c。 方法a有一些逻辑,它调用方法b。 方法b进行api调用,返回Future [String]。 如果方法b的返回值是某个值,则调用方法c。 方法c进行另一个api调用,返回另一个Future [String]。

def a: String = Action { request =>
  val x = b("hello")
  x
}

def b(y: String): Future[String] = {
  val x = ws.url(url).post(y).map { response =>
    val value = response.body
    val z = if (response.body === "hi") response.body else c(response.body)
    z
  }
  x
}

def c(z: String): Future[String] = {
  val x = ws.url(url).post(z).map { response =>
    response.body
  }
  x
}

类似上面的代码。最终,我想将所有内容解析为json对象,但是我无法将Futures作为常规字符串获取。我是scala的新手,请多多投入。

1 个答案:

答案 0 :(得分:0)

您会想要这样的东西:

  def a: Action[AnyContent] = Action.async { _ =>
    b("hello").map(s => Ok(s))
  }

  def b(y: String): Future[String] = {
    ws.url(url).post(y).flatMap { response =>
      if (response.body == "hi") Future.successful(response.body) else c(response.body)
    }
  }

  def c(z: String): Future[String] = {
    ws.url(url).post(z).map { response =>
      response.body
    }
  }

几件事。

1)方法a的类型将是Action[AnyContent],因为您正在创建播放Action。人们通常会忽略操作方法的类型,而让编译器将其弄清楚,这很常见。请注意,如果您的操作更为复杂(例如,它读取JSON请求正文),则其类型可能为Action[something_else](例如,如果您使用Play Json,则为Action[JsValue])。

2)因为b返回了将来,所以您需要使用Action创建Action.async来使用Request => Future[Response]类型的函数创建Action.apply(在调用{{1 }},其功能类型为Request => Response

3)在A中,您需要将map中的StringFuture;我使用Response(即HTTP 200)来执行此操作,尽管您当然可以使用任何合适的方法。

4)在Ok中,b是您的朋友,因为flatMap返回一个c,因此当您使用{时,最终会得到一个Future[String] {1}} ... Future[Future[String]]将其展平为map

5)您需要将flatMap语句的第一个分支包装在Future[String]中,以使两个分支都返回相同的类型ifFuture.successful只是建立一个已经完成的Future[String]

6)最后,您不需要声明值Future.successfulFuturex;每个表达式都解析为它的值,这实际上使事情变得井井有条。