如何将Mono<List<String>>转换为Flux<String>

43

我正在将使用RxJava 1.x编写的小项目转换为Reactor 3.x。一切都很好,唯一的问题是我找不到如何替换flatMap(Observable::from)的合适对应项。我有一个Mono<List<String>>,需要将其转换为Flux<String>


请查看 https://www.baeldung.com/java-mono-list-to-flux。 - Ahmad Abdelghany
4个回答

87

在 Reactor 3 中,from 操作符已经被专门化为几个变体,取决于原始来源(数组、可迭代对象等等)。

在您的情况下,请使用 yourMono.flatMapMany(Flux::fromIterable)


2
方法Mono.flatMap的返回值是Mono,而不是Flux。 - RJ.Hwang
@SimonBaslé,为什么成员引用运算符在 Kotlin 中不起作用? Mono.just(listOfElements).flatMapMany(Flux::fromIterable) //这个不行 我必须写下面这样的代码Mono.just(listOfElements).flatMapMany{ Flux.fromIterable(it) } - rhozet
@rhozet 我不知道,我只知道这在Java中可以工作... 所以这是一个问题,需要向Kotlin编译器专家提问? - Simon Baslé
是的,它在Java中可以工作,可能是编译器专家的问题 :) - rhozet
我认为https://youtrack.jetbrains.com/issue/KT-13003是Kotlin函数引用无法工作的原因。 - lxdr

9
我认为Flux::mergeSequential静态工厂更适合这里:
 Iterable<Mono<String>> monos = ...
 Flux<String> f = Flux.mergeSequential(monos);

这种合并(顺序)将保持给定源可迭代对象内部的排序,并且还将从所有参与源订阅/请求(因此在计算单个结果时可以期望更多的并行化)。

请注意,Flux.mergeSequential 会按顺序订阅每个源,而不会在其间等待完成。如果您严格需要下一个 Mono 在前一个完成后发生(例如,您正在发布到事件队列并且顺序很重要),则应该使用 Flux.concat(monos)。 - Pin

4
感谢Simon,我实现了类似这样的东西:
List<Object> dbObjects = ListObjectsBD();
    List<Dao> daos = mapperObjToDao(dbObjects);
    Flux<Dao> daoFlux = Mono.just(daos).flatMapMany(Flux::fromIterable);

1

另一种方法是使用 flatMapIterable()

将此 Mono 发出的项转换为 Iterable,然后将其元素转发到返回的 Flux 中。

所以它看起来像这样:

List<String> strings = new ArrayList<>();
strings.add("hello");
strings.add("world");
strings.add("!");

Mono<List<String>> monoList = Mono.just(strings);

Flux<String> flux = monoList.flatMapIterable(list -> list);

或者用 Function.identity() 替换 lambda 表达式 list -> list

Flux<String> flux = monoList.flatMapIterable(Function.identity());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接