本文概述如何利用適用於 Java 的 Azure SDK 的分頁與迭代功能,以高效且具生產力的方式處理大型數據集。
Azure Java SDK 內用戶端連結庫所提供的許多作業都會傳回多個結果。 Azure Java SDK 在這些情況下會定義一組可接受的傳回類型,以確保開發人員體驗透過一致性最大化。 同步 API 使用的傳回型別是 PagedIterable,而異步 API 則使用 PagedFlux。 API 因不同使用案例而稍有不同,但在概念上,它們具有相同的需求:
讓您可以輕鬆地逐一查看集合中的每個元素,忽略手動分頁或追蹤接續令牌的任何需求。
PagedIterable和PagedFlux透過逐一查看已反序列化為指定類型T的分頁回應,使這項工作變得簡單。PagedIterable會實作Iterable介面,並提供 API 來接收Stream,同時PagedFlux提供Flux。 在所有情況下,分頁的過程是透明的,只要還有結果可以迭代,迭代就會繼續進行。使能夠逐頁明確地迭代。 這麼做可讓您更清楚地瞭解何時提出要求,並可讓您存取每頁回應資訊。
PagedIterable和PagedFlux都有方法,這些方法會傳回適當的類型來逐頁迭代,而不是逐個元素迭代。
本文會在 Java Azure SDK 同步和異步 API 之間分割。 當您使用同步用戶端時,您會看到同步迭代 API;當使用非同步用戶端時,則會看到非同步迭代 API。
同步分頁和迭代
本節涵蓋同步 API。
逐一查看個別元素
如前所述,最常見的使用案例是個別逐一查看每個元素,而不是逐頁逐一查看。 下列程式代碼範例示範 API 如何 PagedIterable 讓您使用偏好的迭代風格來實作這項功能。
使用 for-each 迴圈
因為 PagedIterable 實作 Iterable,所以您可以逐一查看 元素,如下列範例所示:
PagedIterable<Secret> secrets = client.listSecrets();
for (Secret secret : secrets) {
System.out.println("Secret is: " + secret);
}
使用 Stream
因為 PagedIterable 有定義 stream() 的方法,所以您可以呼叫它以使用標準 Java Stream API,如下列範例所示:
client.listSecrets()
.stream()
.forEach(secret -> System.out.println("Secret is: " + secret));
使用 Iterator
由於 PagedIterable 會實作 Iterable,因此它也具有 iterator() 允許 Java 反覆運算器程式設計樣式的方法,如下列範例所示:
Iterator<Secret> secrets = client.listSecrets().iterator();
while (it.hasNext()) {
System.out.println("Secret is: " + it.next());
}
遍歷頁面
當您處理個別頁面時,您可以逐頁進行迭代,例如當您需要 HTTP 回應資訊,或當接續令牌對於保留迭代歷程很重要時。 無論您是逐頁查看或逐項查看,效能表現和服務呼叫次數都不會有差異。 底層實作會按需載入下一頁,如果您任何時刻取消訂閱 PagedFlux,則不會再呼叫服務。
使用 for-each 迴圈
當您呼叫 listSecrets() 時,您會取得 PagedIterable,它具有 iterableByPage() API。 此 API 會產生 Iterable<PagedResponse<Secret>> ,而不是 Iterable<Secret>。
PagedResponse提供回應元數據和接續令牌的存取權,如下列範例所示:
Iterable<PagedResponse<Secret>> secretPages = client.listSecrets().iterableByPage();
for (PagedResponse<Secret> page : secretPages) {
System.out.println("Response code: " + page.getStatusCode());
System.out.println("Continuation Token: " + page.getContinuationToken());
page.getElements().forEach(secret -> System.out.println("Secret value: " + secret))
}
還有一個 iterableByPage 的重載版本,可以接受接續令牌。 當您想要稍後返回相同的迭代點時,您可以呼叫此方法重載。
使用 Stream
下列範例顯示 streamByPage() 方法如何執行與上述相同的作業。 此 API 也支援接續令牌的重載功能,以便稍後能回到相同的迭代點。
client.listSecrets()
.streamByPage()
.forEach(page -> {
System.out.println("Response code: " + page.getStatusCode());
System.out.println("Continuation Token: " + page.getContinuationToken());
page.getElements().forEach(secret -> System.out.println("Secret value: " + secret))
});
以異步方式觀察頁面和個別元素
本節涵蓋異步 API。 在異步 API 中,網路呼叫發生在與呼叫 subscribe()的主要線程不同的線程中。 這表示主線程可能會在結果可用之前終止。 您必須確保應用程式不會在異步操作完成之前結束。
觀察個別元素
下列範例示範 API 如何 PagedFlux 讓您以異步方式觀察個別元素。 有各種方式可以訂閱 Flux 類型。 如需詳細資訊,請參閱《反應器 3 參考指南》中的簡單建立 Flux 或 Mono 和訂閱它的方法。 此範例是一種情況,其中有三個 Lambda 運算式,分別用於一般取用者、錯誤取用者,以及完成取用者。 擁有這三者都是很好的做法,但在某些情況下,只需要有消費者,還有可能是錯誤消費者。
asyncClient.listSecrets()
.subscribe(secret -> System.out.println("Secret value: " + secret),
ex -> System.out.println("Error listing secrets: " + ex.getMessage()),
() -> System.out.println("Successfully listed all secrets"));
觀察頁面
下列範例展示如何透過 API 讓您以異步方式觀察每個頁面,在此過程中,使用 PagedFlux API,並提供取用者、錯誤取用者和完成取用者。
asyncClient.listSecrets().byPage()
.subscribe(page -> {
System.out.println("Response code: " + page.getStatusCode());
System.out.println("Continuation Token: " + page.getContinuationToken());
page.getElements().forEach(secret -> System.out.println("Secret value: " + secret))
},
ex -> System.out.println("Error listing pages with secret: " + ex.getMessage()),
() -> System.out.println("Successfully listed all pages with secret"));
後續步驟
現在您已熟悉適用於 Java 的 Azure SDK 中的分頁和反覆運算,請考慮檢閱 適用於 Java 的 Azure SDK 中的長時間執行的作業。 長時間執行的作業是運行時間比大多數一般 HTTP 要求更長的作業,通常是因為它們需要伺服器端的一些工作。