Scala 这是不是可以让尾巴递归?
我正在访问一个返回分页JSON响应的HTTP端点。“meta.next”的值 在my response中,type指向响应的下一页。如果此值为null,则不再有页面 取回。 我正在使用Spray IO进行HTTP请求。我收集每个项目中感兴趣的条目 页面响应,并将其与迄今为止收集的内容连接起来。下一步什么时候开始 null,返回所有收集的条目。 我的问题是:有没有办法让tail下面的“getJson(…)”函数递归Scala 这是不是可以让尾巴递归?,scala,future,spray,tail-recursion,Scala,Future,Spray,Tail Recursion,我正在访问一个返回分页JSON响应的HTTP端点。“meta.next”的值 在my response中,type指向响应的下一页。如果此值为null,则不再有页面 取回。 我正在使用Spray IO进行HTTP请求。我收集每个项目中感兴趣的条目 页面响应,并将其与迄今为止收集的内容连接起来。下一步什么时候开始 null,返回所有收集的条目。 我的问题是:有没有办法让tail下面的“getJson(…)”函数递归 case class JsonResponse(meta: Meta, item
case class JsonResponse(meta: Meta, items: List[Item])
val pipeline: Future[HttpRequest => Future[JsonResponse]] = for (
Http.HostConnectorInfo(connector, _) <-
IO(Http) ? Http.HostConnectorSetup("somehost.com", port = 80)
) yield sendReceive(connector) ~> unmarshal[JsonResponse]
// .....
def getJson(relativeUrl: String)(implicit m: Monoid[Future[List[JsObject]]]) : Future[List[JsObject]] = {
val jsr = pipeline.flatMap(_(Get(relativeUrl)))
// Grab only those entries that we are interested in
val objList = jsr.map(js => js.items.collect{ case o if(o.whatever.isDefined) => o.toJson.asJsObject })
jsr.flatMap(js => js.meta.next.map(next => m.append(getJson(next), objList)).getOrElse(objList))
}
case类JsonResponse(meta:meta,items:List[Item])
val管道:未来[HttpRequest=>Future[JsonResponse]]=for(
Http.HostConnectorInfo(连接器,_)解组[JsonResponse]
// .....
def getJson(relativeUrl:String)(隐式m:Monoid[Future[List[JsObject]]):Future[List[JsObject]={
val jsr=pipeline.flatMap((Get(relativeUrl)))
//只抓取我们感兴趣的条目
val objList=jsr.map(js=>js.items.collect{case o if(o.whater.isDefined)=>o.toJson.asJsObject})
jsr.flatMap(js=>js.meta.next.map(next=>m.append(getJson(next),objList)).getOrElse(objList))
}
尾部递归在这里并不适用。当您使用未来的组合器时,您不是在单个堆栈上操作
具体地说,getJson
在任何情况下都会立即返回。通过使用jsr.flatMap
您正在注册一个回调,只有在收到HTTP请求的响应时才会调用该回调。因此,getJson
的下一次调用也将在此上下文中发生,即在e隐式执行上下文
因此,尽管递归仍在算法级别上进行,但它不会导致在一个(或任何)线程的堆栈上添加堆栈帧
关于清理堆栈,您的代码很好。您想使用尾部递归还有其他原因吗?啊。谢谢!是的,我想使用尾部递归的唯一原因是担心清理堆栈。这可能会在返回之前处理很多页面。非常感谢您的清晰解释。我现在觉得有点驼背r没有意识到这一点,但也感到非常宽慰。不,担心。正如
Future
s作为新的通用异步执行原语一样强大,在一开始就很难掌握在所有不同的可能场景中执行是如何流动的。