2016-11-11 117 views
1

在一個典型的分頁API返回與承諾

{ 
    "data": ..., 
    "nextPageHref": <url> 
} 

我如何可以獲取在JavaScript 所有頁面,而無需使用遞歸非遞歸分頁?

(遞歸的解決方案是一樣的東西)

fetchPaginated(url) { 
    return fetch(url).then(result => result.nextPageHref 
    ? fetchPaginated(result.nextPageHref).then(results => _.concat(result, results)) 
    : result 
} 
+0

爲什麼你想這樣做沒有遞歸? –

+0

更好的堆棧跟蹤,如果你使用thenable JS是不是尾遞歸(至少不是無處不在,沒一會兒) – JonathanR

+0

,我相信一個恰當的無極規範庫,應該做類似的太nextTick東西,所以你應該堆棧清除。如果這就是你'更好的堆棧痕跡'的意思。 – Keith

回答

2

AFAIK做到這一點,而不遞歸的唯一方法是異步等候的原生支持,並使用一個for循環。請注意,編譯的async-await也會編譯成一些僞裝的遞歸代碼。

但是這個遞歸不是遞歸的,因爲調用fetchPaginated是從回調中調用的,所以同步調用棧在回調之前總是被清空(因此它跟尾遞歸沒有關係)。如果您關心瀏覽器異步調用堆棧(這只是爲了調試目的,我們不需要異步調用堆棧來運行程序),我認爲瀏覽器開發人員工具中應該有一個複選框來關閉它。

enter image description here

+0

這是一個非常好的點,調用函數將在遞歸調用發生之前完成。謝謝! – JonathanR

+0

真的很好的一步一步的解釋[這裏](http://stackoverflow.com/a/37406665/3099140) – JonathanR

0

我想你可以根據請求的頁面發送的總頁數 - /get_page?page_num=4

{ 
    "data": ..., 
    "number_of_pages": 73 
} 

這會讓你知道,如果你可以要求第5頁。

此外,它的優點在於可以讓用戶跳過5頁或訪問的最後一頁,你不能用approa做你建議。

+0

我的API僅支持基於令牌的分頁。我必須抓取頁面'n'才能獲取頁面'n + 1'(請注意,許多現實生活中的API,例如谷歌和Facebook)遵循這種模式來強制人們實際使用分頁,而不是通過同時請求每頁來繞過它) – JonathanR

+0

@JonathanR那麼你爲什麼要繞過分頁? –

+0

您可以將當前頁面分配給令牌,然後使用'/ get_next_page'獲取下一頁,'/ get_first_page'重置計數器。 –