2016-02-07 210 views
11

第一:這是我使用RxJs的第一個項目,我想我會通過使用它來學習最好的。RxJs可觀察分頁

我發現了這樣的回答:Turning paginated requests into an Observable stream with RxJs 但它說,在註釋:

你超過最大調用堆棧依然。大約有430頁返回。我認爲遞歸可能不是這裏最好的解決方案

我想查詢YouTube數據API,結果返回頁面,我需要通過它們分頁。 我想象像這樣的工作流程可以工作: 1)發起呼叫 2)檢查響應具有「nextPageToken這個」 3)如果有,做另一個請求到的Youtube API 4)如果不是,光潔度

So to do this I could Imagine the following Observables/streams: 
FirstRequestStream -A-X---------------> 
ResponseStream  -A-A-A-A--X--------> 
RequestStream  -I-A-I-A-----------> 
A = Action 
I = Info from upper stream 
X = Termination 

(不知道這圖是正確的我做它的方式)

所以ResponseStream取決於FirstRequestStream和RequestStream(使用合併功能)。 RequestStream依賴於ResponseStream(這是否稱爲循環觀察?)

- 這是正確的方法嗎?

-Are'循環observable'是一件好事,他們甚至有可能嗎?(我有問題創建一個)。

- 我應該先嚐試其他方法嗎?

- 是否有可能創建相互依賴的可觀察流?

謝謝你的幫助。

回答

15

您正在過度複雜化這個問題,使用Rx.Observable.defer可以輕鬆解決問題。

想法是,您正在創建延遲observable(因此它將被創建並且僅在預訂後纔開始獲取數據),並將其與同一個可觀察值連接起來,但對於下一頁將與下一頁連接起來,以及等等...。所有這些都可以在沒有遞歸的情況下完成。

下面是代碼的外觀:

function fetchItems(params, pageToken) { 
    return Observable.defer(
    () => fetchSomething({ 
     params, 
     pageToken, 
    }) 
     .flatMap(({ items, nextPageToken }) => { 
     const items$ = Observable.fromArray(items); 
     const next$ = nextPageToken 
      ? fetchItems(params, nextPageToken) 
      : Observable.empty(); 

     return Observable.concat(
      items$, 
      next$ 
     ); 
     }) 
); 
} 

const items$ = fetchItems(params) 
    // process all items until end 

const firstTenItems$ = fetchItems(params) 
    .take(10); 
    // process only first 10 items, without fetching all of the data 

哪裏fetchSomething是函數接受一些參數和返回觀察到的結果。它可以從庫方法如下創建:

import {Observable} from 'rx'; 
import google from 'googleapis'; 

const yt = google.youtube({ 
    version: 'v3', 
    auth: // your apiKey here, 
}); 

const getChannel = Observable.fromNodeCallback(yt.channels.list, yt, r=>r); 
+0

但據我瞭解,這將讓所有的分頁通話7,如果沒有人感興趣的結果 - 例如,在用戶沒有按下「下一步頁面「按鈕,完成」無限滾動「。如何修改這個邏輯來允許這樣的事情? –

+0

@torazaburo此可觀察項目沒有延期(「懶惰」),所以它只會在某人訂閱了它之後纔開始提出請求,並且在您退訂時停止。因此,如果您只需從流中「取」幾個項目,只需要獲取所需的頁面(不是全部),請參閱答案中的代碼示例。 –