为列表中的每个 URL 发送 WS 请求并将响应映射到新列表
Send a WS request for each URL in a list and map the responses to a new list
我正在 Play with Scala 中开发一个 REST 服务器,它有时需要在一个或多个其他 Web 服务上请求数据。基于这些服务的响应,服务器必须组成一个统一的结果供以后使用。
示例:
www.someplace.com
上的事件 C 需要执行。为了执行事件 C,www.anotherplace.com
上的事件 A 和 www.athirdplace.com
上的事件 B 也必须执行。
事件 C 有一个 Seq(www.anotherplace.com, www.athirdplace.com)
,我想从中迭代并分别向每个 URL 发送一个 WS 请求,以检查是否执行了 B 和 C。
假设 GET 到这些 URLs returns true
或 false
如何收集每个请求的响应(最好合并到一个列表中)并断言每个响应等于 true
?
编辑:一个事件可以包含任意数量的URL。所以我无法事先知道我需要发送多少 WS 请求。
看看 the documentation 看看你是否可以让他们的例子工作。
尝试这样的事情:
val futureResponse: Future[WSResponse] = for {
responseOne <- WS.url(urlOne).get()
responseTwo <- WS.url(responseOne.body).get()
responseThree <- WS.url(responseTwo.body).get()
} yield responseOne && responseTwo && responseThree
您可能需要解析 WebService 的响应,因为它们(可能)不会 return 布尔值,但您会明白的。
简答
您可以使用 sequence
method available on Future
对象。
例如:
import scala.concurrent.Future
val urls = Seq("www.anotherplace.com", "www.athirdplace.com")
val requests = urls.map(WS.url)
val futureResponses = Future.sequence(requests.map(_.get()))
聚合Future
请注意 futureResponses
的类型将为 Future[Seq[WSResponse]]
。现在您可以处理结果了:
futureResponses.map { responses =>
responses.map { response =>
val body = response.body
// do something with response body
}
}
更多详情
来自 sequence
方法的 ScalaDocs:
Transforms a TraversableOnce[Future[A]] into a
Future[TraversableOnce[A]]. Useful for reducing many Futures into a
single Future.
请注意,如果您传递给 sequence
的任何 Future
失败,则生成的 Future
也将失败。只有当所有 Future
都成功完成时,结果才会成功完成。这对于某些用途是有好处的,特别是如果你想同时发送请求,而不是一个接一个地发送请求。
我正在 Play with Scala 中开发一个 REST 服务器,它有时需要在一个或多个其他 Web 服务上请求数据。基于这些服务的响应,服务器必须组成一个统一的结果供以后使用。
示例:
www.someplace.com
上的事件 C 需要执行。为了执行事件 C,www.anotherplace.com
上的事件 A 和 www.athirdplace.com
上的事件 B 也必须执行。
事件 C 有一个 Seq(www.anotherplace.com, www.athirdplace.com)
,我想从中迭代并分别向每个 URL 发送一个 WS 请求,以检查是否执行了 B 和 C。
假设 GET 到这些 URLs returns true
或 false
如何收集每个请求的响应(最好合并到一个列表中)并断言每个响应等于 true
?
编辑:一个事件可以包含任意数量的URL。所以我无法事先知道我需要发送多少 WS 请求。
看看 the documentation 看看你是否可以让他们的例子工作。 尝试这样的事情:
val futureResponse: Future[WSResponse] = for {
responseOne <- WS.url(urlOne).get()
responseTwo <- WS.url(responseOne.body).get()
responseThree <- WS.url(responseTwo.body).get()
} yield responseOne && responseTwo && responseThree
您可能需要解析 WebService 的响应,因为它们(可能)不会 return 布尔值,但您会明白的。
简答
您可以使用 sequence
method available on Future
对象。
例如:
import scala.concurrent.Future
val urls = Seq("www.anotherplace.com", "www.athirdplace.com")
val requests = urls.map(WS.url)
val futureResponses = Future.sequence(requests.map(_.get()))
聚合Future
请注意 futureResponses
的类型将为 Future[Seq[WSResponse]]
。现在您可以处理结果了:
futureResponses.map { responses =>
responses.map { response =>
val body = response.body
// do something with response body
}
}
更多详情
来自 sequence
方法的 ScalaDocs:
Transforms a TraversableOnce[Future[A]] into a Future[TraversableOnce[A]]. Useful for reducing many Futures into a single Future.
请注意,如果您传递给 sequence
的任何 Future
失败,则生成的 Future
也将失败。只有当所有 Future
都成功完成时,结果才会成功完成。这对于某些用途是有好处的,特别是如果你想同时发送请求,而不是一个接一个地发送请求。