繁体   English   中英

Scala Play框架期货

[英]Scala Play framework futures

我有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的新手,希望能得到一些帮助。

您会想要这样的东西:

  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返回一个Request => Future[Response] ,所以您需要使用Action.async创建Action ,该Action Action.async一个Request => Future[Response]类型的功能(在调用Action.apply之前,它具有一个Request => Response类型的功能) 。

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

4)在bflatMap是您的朋友,因为c返回一个Future[String] ,因此当您使用map时,您最终得到一个Future[Future[String]] ... flatMap平为Future[String]

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

6)最后,您不需要声明值xyz 每个表达式都解析为其价值,这确实使事情变得井井有条。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM