rx用expand達成recursive
昨天看了一部影片,是由大神Ben介紹expand的功能
這篇是跟著實作並且去理解使用,將透過pagination的應用來做介紹,每頁10筆,假設不確定會有幾頁,要全部都拿回來的話可以怎麼實作
模擬API資料
首先我們要先有模擬api的功能,因此我們寫一段rx並帶上500的timer作為示意,這邊就固定只給到10頁
1 | const getPagedData = index => timer(500).pipe( |
執行後可以看到這樣的資料,那初期的準備就完成了
1 | { |
recursive實作
如果用原本熟悉的那些operator下去做,會怎麼實作呢?這時候我會使用subject來達到這個目的
1 | const nextPage$ = new Subject(); |
其實subscribe的那段判斷,可以拉上去變成用tap來做
1 | const source = nextPage$.pipe( |
重構改用expand
但rx有提供更好的寫法,就是expand
先來看看官方的說法
Recursively projects each source value to an Observable which is merged in the output Observable.
這非常類似於mergeMap
但在條件完成前就是不斷的呼叫同一個方法,直到呼叫EMPTY
為止,那就來試著改寫上面的那段程式
1 | expand({nextPageIndex} => nextPageIndex !== undefined ? getPagedData(nextPageIndex) : EMPTY) |
哇賽,整個變得好簡潔呢,但是來源資料要怎麼給呢?
因為我們改成用expand
,因此資料要符合他的格式,才能讓他遞迴下去,因此就改成用這樣的寫法
1 | const source = of({nextPageIndex: 0}).pipe( |
結論
雖然這個應用場景我還沒遇到,但能多學到一個operator是還蠻不錯的,畢竟rx所提供的operator還蠻多的,而且只看範例完全無法想像那個應用情境,剛好有大神開示,試著自己玩玩看還不錯!
完整的程式碼可以到這邊來看!