如何延迟发射 iterable Spring Boot Flux 中的每个项目
How to delay emitting each item in iterable Spring Boot Flux
我的问题略有不同,但我可以用以下方式描述问题。
我想要的是一些代码,每个延迟周期(3 秒)发出一个项目。但是当我点击 /flux
URL 时,页面等待 3 秒并给出所有 4 个项目。这意味着它会在 3 秒后发出所有项目,而不是每 3 秒发出一个项目。
@RestController
@RequestMapping("/flux")
public class MyController {
List<Item> items = Arrays.asList(
new Item("name1","description1"),
new Item("name2","description2"),
new Item("name3","description3"),
new Item("name4","description4"));
@GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE)
Flux<Item> getItems(){
return Flux.fromIterable(items)
.delayElements(Duration.ofSeconds(3));
}
}
@Data
@AllArgsConstructor
class Item{
String name;
String description;
}
更新
我看到这个 来解释如何在 RxJava 中执行此操作,所以我尝试了这个。但是 ZipWith
结果更糟。现在页面等待 12 秒。这意味着只有当 Flux 完成时才会发送浏览器响应...不知道为什么。
Flux<Item> getItems(){
return Flux.fromIterable(items)
.zipWith(Flux.interval(Duration.ofSeconds(3)),(item,time)->item);
}
p.s。使用 Spring WebFlux 依赖项,因此本地启动时使用 Netty 而不是 Tomcat。
我们可以使用 delayElements(Duration delay)
告诉反应器在特定延迟后发射元素。它总是尝试在特定持续时间后发出元素而不阻塞。
将此 URL 放入 google chrome 浏览器或任何其他消费者客户端,如 curl
而不是邮递员。
卷曲
curl --location --request GET 'http://localhost:8080/fluxv2' \
--header 'Content-Type: text/event-stream' \
--data-raw ''
不要尝试使用 postman 测试 API,因为 postman 目前不支持流式传输 API。
@RestController
@RequestMapping("/fluxv2")
public class MyController {
Flux<String> stringFlux = Flux.fromIterable(List.of("CM", "Abdullah", "Khan"));
@GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE)
Flux<String> getItems() {
return stringFlux.delayElements(Duration.ofSeconds(3)).log();
}
}
Logs shown that elements are emitting after specific delay
问题不在代码中,问题在浏览器中。
如果我们使用 Chrome,上面提到的代码都按预期工作。但不适用于 safari 浏览器
我的问题略有不同,但我可以用以下方式描述问题。
我想要的是一些代码,每个延迟周期(3 秒)发出一个项目。但是当我点击 /flux
URL 时,页面等待 3 秒并给出所有 4 个项目。这意味着它会在 3 秒后发出所有项目,而不是每 3 秒发出一个项目。
@RestController
@RequestMapping("/flux")
public class MyController {
List<Item> items = Arrays.asList(
new Item("name1","description1"),
new Item("name2","description2"),
new Item("name3","description3"),
new Item("name4","description4"));
@GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE)
Flux<Item> getItems(){
return Flux.fromIterable(items)
.delayElements(Duration.ofSeconds(3));
}
}
@Data
@AllArgsConstructor
class Item{
String name;
String description;
}
更新
我看到这个 ZipWith
结果更糟。现在页面等待 12 秒。这意味着只有当 Flux 完成时才会发送浏览器响应...不知道为什么。
Flux<Item> getItems(){
return Flux.fromIterable(items)
.zipWith(Flux.interval(Duration.ofSeconds(3)),(item,time)->item);
}
p.s。使用 Spring WebFlux 依赖项,因此本地启动时使用 Netty 而不是 Tomcat。
我们可以使用 delayElements(Duration delay)
告诉反应器在特定延迟后发射元素。它总是尝试在特定持续时间后发出元素而不阻塞。
将此 URL 放入 google chrome 浏览器或任何其他消费者客户端,如 curl
而不是邮递员。
卷曲
curl --location --request GET 'http://localhost:8080/fluxv2' \
--header 'Content-Type: text/event-stream' \
--data-raw ''
不要尝试使用 postman 测试 API,因为 postman 目前不支持流式传输 API。
@RestController
@RequestMapping("/fluxv2")
public class MyController {
Flux<String> stringFlux = Flux.fromIterable(List.of("CM", "Abdullah", "Khan"));
@GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE)
Flux<String> getItems() {
return stringFlux.delayElements(Duration.ofSeconds(3)).log();
}
}
Logs shown that elements are emitting after specific delay
问题不在代码中,问题在浏览器中。 如果我们使用 Chrome,上面提到的代码都按预期工作。但不适用于 safari 浏览器