如何延迟发射 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 浏览器