flux中的map和doOnNext有哪些区别?(即project reactor)

15

在Flux中,map函数也会针对flux中的每个项目执行。而doOnNext函数也会在flux中每个(发射的)项目上执行。从用户的角度来看,这两者有什么区别?为什么存在两个类似的方法?能否通过一个简单的用例来解释一下?

2个回答

17

只是想添加到其他好的答案 - 当我开始使用doOnNext()时,我错过了一个重要的部分,那就是它不是“函数式”mapflatMap的 “消费者”对应物。

doOnNext有点像在发布者发出项时执行的回调,但它不会影响流程,即它立即返回原始的发布者。
例如:最初我认为我可以做以下操作:

Mono.from()
    .doOnNext(doSomethingConsumer)
    .doOnNext(thenDoSomethingElseConsumer);

当我对返回值不感兴趣且这些操作将按顺序应用时。
这是完全错误的!实际上,两个doOnNext()操作符会立即被应用。


3
你想做的事情正确的做法是什么? - Matt R
2
我尝试运行了两个doOnNext。其中一个带有睡眠,但是这两个没有并行执行。第二个doOnNext等待第一个doOnNext完成后才执行。所以它们是按顺序应用的?https://gist.github.com/asthinasthi/5d3cc12e853449063a0e0a724e704b4a - Hexy

17

简述: Flux#doOnNext 用于副作用,Flux#map 用于同步映射一个类型到另一个类型。

如果我们查看 documentation ,它对于 doOnNext 给出了以下说明:

Flux<T> doOnNext(Consumer<? super T> onNext)
Add behavior (side-effect) triggered when the Flux emits an item.

这意味着在doOnNext中,我们可以进行副作用操作,比如记录日志或在其他地方进行rest调用等等。我们还返回类型为T的Flux,与doOnNext接收到的相同,因此没有类型更改。
另一方面,如果我们看Map
Flux<V> map(Function<? super T,? extends V> mapper)
Transform the items emitted by this Flux by applying a synchronous function to 
each item.

我们可以看到这里可以应用同步函数,基本上我们可以对发出的值进行一些操作。添加一些内容、减去一些内容、以某种方式改变它,在这里我们可以转换它,例如将其map为其他内容。
如果我们查看map中的类型,我们可以看到map会发出一些super T,但它会返回一些extends V的东西。
这是一个典型的Java泛型模式,如果您想了解更多,请观看Joshua Bloch关于泛型的讲话。整个视频都很好看,会比我解释得更好。
但我想指出的是,通过使用map,您将返回一个不同的类型。您从flux中获取一些super T,然后将其映射为其他extends V的东西。

1
感谢您的回复。map函数可以做“doOnNext函数可以做”的事情。那么,doOnNext函数能够实现哪些功能,而map函数却不能实现呢? - Satheessh Chinnusamy
它不会消耗项目,map函数会执行。 - Toerktumlare
1
在我看来,doOnNext 提供了接收到的输入的不可变性。但在 map 中则不然。 - Hexy

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