如何结合 Scala Play2 中多个响应的数据?
How combine data from several responses in Scala Play2?
我需要对不同的 URL 做一些请求,从他们的响应中获取数据并将这些信息放在一个列表中,但我对这个主题有一些误解。
1) 对于一个请求,我做了
def doRequest: Future[WSResponse] = {
client
.url("MY_URL")
.withRequestTimeout(5000)
.get()}
然后我解析 json 以响应我的对象列表:
def list: Future[List[FoobarEntry]] = {
doRequest.map {
response => {
val json = response.json \ "foobar"
json.validate[List[FoobarEntry]] match {
case js:JsSuccess[List[FoobarEntry]]=>
js.get
case e:JsError => Logger.error(JsError.toFlatJson(e).toString()); List()
}
}
}}
我认为对于几个 url 我应该写一些看起来像
def doRequests: List[Future[WSResponse]] = {
List(client
.url("URL_1")
.withRequestTimeout(5000)
.get(),
client
.url("URL_2")
.withRequestTimeout(5000)
.get())}
但是如何像我的 def list: Future[List[FoobarEntry]]
一样解析这个 Future[WSResponse] 列表?
由于您将未来的响应放在列表中,因此您必须将每个未来的响应映射到将其转换为 FoobarEntry
的解析逻辑。像这样:
val responseFutures: List[Future[WSResponse]] = ???
val foobarFutures: List[Future[FoobarEntry]] =
responseFutures.map(future => future.map(response => parse(response)))
现在您有了一个未来已解析响应的列表,但是要在所有响应都到达时执行某些操作,您需要对该列表进行排序:
val futureFoobars = Future.sequence(foobarFutures)
因此,顺序可以帮助您从 C[Future[A]]
到 Future[C[A]]
使用 for-comprehensions。
val request1 = client.url("URL_1").withRequestTimeout(5000).get()
val request2 = client.url("URL_2").withRequestTimeout(5000).get()
val result: Future[List[FoobarEntry]] = for {
res1: WSResponse <- request1
res2: WSResponse <- request2
} yield List(res1, res2).map(parse).flatten
def parse(response: WSResponse): List[FoobarEntry] = {
val json = response.json \ "foobar"
json.validate[List[FoobarEntry]] match {
case js:JsSuccess[List[FoobarEntry]]=>
js.get
case e:JsError => Logger.error(JsError.toFlatJson(e).toString())
List()
}
我需要对不同的 URL 做一些请求,从他们的响应中获取数据并将这些信息放在一个列表中,但我对这个主题有一些误解。 1) 对于一个请求,我做了
def doRequest: Future[WSResponse] = {
client
.url("MY_URL")
.withRequestTimeout(5000)
.get()}
然后我解析 json 以响应我的对象列表:
def list: Future[List[FoobarEntry]] = {
doRequest.map {
response => {
val json = response.json \ "foobar"
json.validate[List[FoobarEntry]] match {
case js:JsSuccess[List[FoobarEntry]]=>
js.get
case e:JsError => Logger.error(JsError.toFlatJson(e).toString()); List()
}
}
}}
我认为对于几个 url 我应该写一些看起来像
def doRequests: List[Future[WSResponse]] = {
List(client
.url("URL_1")
.withRequestTimeout(5000)
.get(),
client
.url("URL_2")
.withRequestTimeout(5000)
.get())}
但是如何像我的 def list: Future[List[FoobarEntry]]
一样解析这个 Future[WSResponse] 列表?
由于您将未来的响应放在列表中,因此您必须将每个未来的响应映射到将其转换为 FoobarEntry
的解析逻辑。像这样:
val responseFutures: List[Future[WSResponse]] = ???
val foobarFutures: List[Future[FoobarEntry]] =
responseFutures.map(future => future.map(response => parse(response)))
现在您有了一个未来已解析响应的列表,但是要在所有响应都到达时执行某些操作,您需要对该列表进行排序:
val futureFoobars = Future.sequence(foobarFutures)
因此,顺序可以帮助您从 C[Future[A]]
到 Future[C[A]]
使用 for-comprehensions。
val request1 = client.url("URL_1").withRequestTimeout(5000).get()
val request2 = client.url("URL_2").withRequestTimeout(5000).get()
val result: Future[List[FoobarEntry]] = for {
res1: WSResponse <- request1
res2: WSResponse <- request2
} yield List(res1, res2).map(parse).flatten
def parse(response: WSResponse): List[FoobarEntry] = {
val json = response.json \ "foobar"
json.validate[List[FoobarEntry]] match {
case js:JsSuccess[List[FoobarEntry]]=>
js.get
case e:JsError => Logger.error(JsError.toFlatJson(e).toString())
List()
}