Azure SDK for Java 中的分页和迭代
本文概述如何使用 Azure SDK for Java 的分页和迭代功能,有效且高效地处理大型数据集。
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
API 使用你偏好的迭代样式来实现此功能。
使用 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));
使用迭代器
因为 PagedIterable
实现 Iterable
,所以它还具有用于实现 Java 迭代器编程样式的 iterator()
方法,如以下示例所示:
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()
的主线程中。 这意味着主线程可能会在结果出来之前终止。 你需要确保在异步操作完成之前,应用程序不会退出。
观察单个元素
以下示例演示如何通过 PagedFlux
API 来异步观察单个元素。 可通过多种方法订阅 Flux 类型。 有关详细信息,请参阅 Reactor 3 Reference Guide(Reactor 3 参考指南)中的 Simple Ways to Create a Flux or Mono and Subscribe to It(创建 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"));
观察页
以下示例演示 PagedFlux
API 如何通过使用 byPage()
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"));
后续步骤
现在,你已熟悉 Azure SDK for Java 中的分页和迭代,接下来请考虑查看 Azure SDK for Java 中的长期操作。 与大多数常见的 HTTP 请求相比,长期操作的运行时间更长,这通常是因为它们需要在服务器端执行一些操作。