是否有更多功能性的方法来执行此请求序列?

时间:2013-12-14 19:10:41

标签: json scala spray spray-json

有一个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 ++ _)
      }

我的问题是:有没有办法让这个功能更强大? (避免递归或者使其尾递归?)。或者甚至是喷雾支持这种聚合吗?

2 个答案:

答案 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

  1. 请求spray启动HTTP请求(立即返回未来)
  2. 使用匿名函数在该未来调用flatMap以在完成时运行。这也会立即回归未来。
  3. 将该未来发送给来电者