有一个REST api,它返回一个json,其中包含一个jsons列表(命名结果)和一个url到下一批结果(这个url等于null,最后一个" page")。我想汇总整个结果(将所有jsons列表连成一个)。我正在使用spray-client来执行GET请求,这就是我提出的:
val request: HttpRequest => Future[MyResponse] = sendReceive ~> unmarshal[MyResponse]
def getCandidatesStartingFrom(url: String): Future[List[Candidate]] =
request(Get(url)).flatMap {
response =>
val next = response.next match {
case Some(nextUrl) => getCandidatesStartingFrom(nextUrl)
case None => Future.successful(Nil)
}
next.map(response.results ++ _)
}
我的问题是:有没有办法让这个功能更强大? (避免递归或者使其尾递归?)。或者甚至是喷雾支持这种聚合吗?
答案 0 :(得分:0)
request(Get(url)).flatMap {
response =>
val next = response.next match {
case Some(nextUrl) => getCandidatesStartingFrom(nextUrl)
case None => Future.successful(Nil)
}
next.map(response.results ++ _)
}
可以写成如下。但这并没有太大的改善。
for{
response <- request(Get(url))
nextUrl <- response.next
.map(getCandidatesStartingFrom)
.getOrElse(Future.successful(Nil))
} yield response.results ++ nextUrl
答案 1 :(得分:0)
它目前不是递归的。您对getCandidatesStartingFrom
的“递归”调用实际上并不在父getCandidatesStartingFrom
调用的调用堆栈中,而是在传递给flatMap
的匿名lambda中。
即getCandidatesStartingFrom
:
flatMap
以在完成时运行。这也会立即回归未来。