[英]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
,您需要将Future
的String
map
到Response
; 我当然使用Ok
(即HTTP 200)来执行此操作,尽管您当然可以使用任何合适的方法。
4)在b
, flatMap
是您的朋友,因为c
返回一个Future[String]
,因此当您使用map
时,您最终得到一个Future[Future[String]]
... flatMap
平为Future[String]
。
5)您需要将if
语句的第一个分支包装在Future.successful
,以使两个分支都返回相同的类型Future[String]
。 Future.successful
只会构建一个已经完成的Future
。
6)最后,您不需要声明值x
, y
和z
; 每个表达式都解析为其价值,这确实使事情变得井井有条。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.