Я удаляю конечную точку HTTP, которая возвращает разбитый на панель ответ JSON. Значение «meta.next» в моем типе ответа указывает на следующую страницу ответа. Когда это значение равно NULL, больше нет страниц для извлечения. Я использую Spray IO для создания HTTP-запросов. Я собираю записи, представляющие интерес в каждом ответе на странице , и объединяйте их с тем, что было собрано до сих пор. Когда следующий становится null, я возвращаю все собранные записи. Мой вопрос: Есть ли способ сделать функцию getJson (...) ниже хвоста рекурсивной?Может ли это быть регенерированным хвостом?
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))
}
Ah. Спасибо! Да, единственная причина, по которой я хотел использовать хвостовую рекурсию, - это страх выдувать мой стек. Это может привести к обработке многих страниц перед возвратом. Большое спасибо за ваше четкое объяснение. Теперь я чувствую себя немного глупым, потому что не понимаю этого, но также очень облегчен. –
Нет, беспокоится. Такие мощные, как «Будущие», являются новым общим асинхронным примитивом выполнения, поэтому трудно вначале понять, как выполнение выполняется во всех различных сценариях. – jrudolph