共用方式為


適用於 Java 的 Azure SDK 中的分頁和迭代

本文概述如何利用適用於 Java 的 Azure SDK 的分頁與迭代功能,以高效且具生產力的方式處理大型數據集。

Azure Java SDK 內用戶端連結庫所提供的許多作業都會傳回多個結果。 Azure Java SDK 在這些情況下會定義一組可接受的傳回類型,以確保開發人員體驗透過一致性最大化。 同步 API 使用的傳回型別是 PagedIterable,而異步 API 則使用 PagedFlux。 API 因不同使用案例而稍有不同,但在概念上,它們具有相同的需求:

  • 讓您可以輕鬆地逐一查看集合中的每個元素,忽略手動分頁或追蹤接續令牌的任何需求。 PagedIterablePagedFlux透過逐一查看已反序列化為指定類型T的分頁回應,使這項工作變得簡單。 PagedIterable 會實作 Iterable 介面,並提供 API 來接收 Stream,同時 PagedFlux 提供 Flux。 在所有情況下,分頁的過程是透明的,只要還有結果可以迭代,迭代就會繼續進行。

  • 使能夠逐頁明確地迭代。 這麼做可讓您更清楚地瞭解何時提出要求,並可讓您存取每頁回應資訊。 PagedIterablePagedFlux都有方法,這些方法會傳回適當的類型來逐頁迭代,而不是逐個元素迭代。

本文會在 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 要求更長的作業,通常是因為它們需要伺服器端的一些工作。