简体   繁体   English

订阅一个空的 Flux 会导致无限循环

[英]Subscribing to an empty Flux causes an infinite loop

I have a call chain that looks something like this:我有一个看起来像这样的调用链:

public ResponseEntity<Flux<Entity>> create() {
    return ResponseEntity.ok(saveList());
}

public Flux<Entity> saveList() {
    if(list.isEmpty()) return Flux.empty();
    return repository.saveAll(list);
}

Whether I return Flux.empty() directly or send it to the database call, if I add a .map() call onto the create() chain, it does not execute because there are no elements, as we would expect.无论我是直接返回Flux.empty()还是将其发送到数据库调用,如果我将.map()调用添加到create()链上,它都不会执行,因为没有元素,正如我们所期望的那样。 However, if I add a .switchIfEmpty() , this also does not execute.但是,如果我添加.switchIfEmpty() ,这不会执行。 No matter what combination of handlers I have tried for an empty Flux, it always results in an infinite loop, I assume because it's waiting for an element to be added so it can emit it.无论我为一个空的 Flux 尝试过什么样的处理程序组合,它总是会导致无限循环,我认为是因为它正在等待添加一个元素以便它可以发出它。

The documentation suggests Flux.empty() should complete without emitting anything, but logging the Flux shows only onSubscribe() and request() are called, so it is not completing, hence why the.文档建议Flux.empty()应该完成而不发出任何东西,但是记录 Flux 显示只调用了onSubscribe()request() ,所以它没有完成,因此为什么。 switchIfEmpty() is also not called. switchIfEmpty()也不会被调用。

What do I need to do to get an empty Flux to complete when I subscribe to it?当我订阅它时,我需要做什么才能让一个空的 Flux 完成?

Any non-zero-sized Flux succeeds, but I have tried a number of different empty Flux types, such as from an array, which all fail.任何非零大小的 Flux 都会成功,但我已经尝试了许多不同的空 Flux 类型,例如来自数组的,但都失败了。

I am using a hard-coded, non empty Publisher for switchIfEmpty() , since the implication seems to be that this is strictly necessary.我正在为switchIfEmpty()使用硬编码的非空 Publisher,因为这似乎是绝对必要的。

Since I have not received an answer (as usual, I might add) , I have created a workaround.由于我没有收到答复(像往常一样,我可能会补充) ,我创建了一个解决方法。

First, I collect the response in a list, then use Flux.error() and then complete the execution with onErrorComplete() in the caller.首先,我将响应收集在一个列表中,然后使用Flux.error() ,然后在调用者中使用onErrorComplete() () 完成执行。

public Flux<ListItem> create(List<ListItem> originalList) {
    return repository.get()
    .collectList()
    .flatMapMany(list -> {
        if(list.isEmpty()) return Flux.error(new IllegalStateException());
        return repository.saveAll(list);
    })
    .switchIfEmpty(repository.saveAll(originalList)
    .onErrorComplete();

Since my flatMapMany() relies on an initial database call, I additionally use switchIfEmpty() to catch any situation with an empty response.由于我的flatMapMany()依赖于初始数据库调用,因此我还使用switchIfEmpty()来捕获任何响应为空的情况。 This does not necessarily fit every use case, but may be relevant for the types of problems that may result in an empty Flux.这不一定适合所有用例,但可能与可能导致空 Flux 的问题类型相关。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM