概要
PagedIterableのコードを確認したため、備忘録として残しておきます。
PagedIterableは、 マイクロソフトのライブラリにおいて定義されているページング処理を行うためのクラスです。
使い方
iteratorを使用することで、ページ毎にアクセスできるようになっています。
val iterator = hogeClient.listHoges.byPage().iterator() while (true) { if (!iterator.hasNext()) break val page = iterator.next() }
また、foreachやmap, flatMap等を使用することで全ての結果を一度に取得することもできます。
val result = hogeClient.listHoges.byPage().flatMap { // do something }
byPage()を呼ぶ時呼ばない時の挙動の違い
byPage()による違いが気になったので、少しコードを追ってみました。
結論
結論としては、
- byPageを呼ぶ...pageIdを用いて取得したページの値(リスト)をPagedResponseとして返却します。次のnext()でも、次ページを取得&返却します。
- byPageを呼ばない...ページ毎に取得すること自体は変わりません。しかし、1ページ分の値を取得し、そのレスポンスの中のアイテムを一つずつ返却します。1ページの中のアイテムを返し終わった後、次のページを取得する流れで処理が進みます。
コードの内容
コード内の主な登場人物は
- PagedIterable
- PagedResponseIterable
- PageItemIterator
- PagedResponseIterator
の4つです。
byPageを使用する場合の動作
- ClientクラスのlistHoge()がpagedIterableを返却する。
- byPage()がPagedResponseIterableを返却する
- PagedResponseIterableのiterator()がPageResponseIteratorを返却する
- PageResponseIterator#next()を呼び、実際のページ取得処理が始まる。
- 取得結果からpageIdを取得し、保存する。
- 次のnext()で、同pageIdを使用して後続のページを取得する。 という流れになっています。
byPage()を使用せず、pagedIterable#iteratorを呼ぶ場合の動作
- PagedIterable#iterator()を呼び、PageItemIteratorを生成する。
- PageItemIteratorの引数として、PagedIterable#byPage()#iteratorを呼び、渡す。 (結局、byPageは呼ばれている)
- PageResponseIterator#next()を呼び、実際のページ取得処理が始まる。
- 取得結果をDequeに入れる
- 取得結果からpageIdを取得し、保存する。
- Dequeに値があればpopする
- 次のnext()で、Dequeに値があればpopする。Dequeが空であればpageIdを使用して後続のページを取得する。
という流れになっています。
byPageという名前の通り、 page毎の値を返すか、アイテム一つずつを返すかの違いになっているようです。