[英]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.