map 和 doOnNext 有什么区别?(即项目反应堆)

Sat*_*amy 4 reactive-programming reactive spring-webflux spring-reactive

在 Flux 中,地图函数也为通量中的每个项目执行。对于通量中的每个项目(发射的),doOnNext 函数也被执行。从用户角度看有什么区别?为什么存在两种类似的方法?可以用简单的易用性来解释。

fyr*_*kov 9

只是为了补充上面的好答案 - 我认为我开始使用时缺少的一个重要部分doOnNext()是它不是“类函数”mapflatMap.

doOnNext是一种回调,在发布者发出项目时执行,但不影响流程,即立即返回原始发布者。
示例:最初我以为我可以做这样的事情

Mono.from()
    .doOnNext(doSomethingConsumer)
    .doOnNext(thenDoSomethingElseConsumer);
Run Code Online (Sandbox Code Playgroud)

当我对返回值不感兴趣并且这些东西将按顺序应用时。
这是完全错误的!事实上,这两个doOnNext()运算符都是立即应用的。

  • 做你想做的事的正确方法是什么? (3认同)
  • 我尝试运行 2 doOnNext。1 有一个睡眠,两者没有并行执行。第二个 doOnNext 等待第一个 doOnNext 完成。那么它们是按顺序应用的吗?https://gist.github.com/asthinasthi/5d3cc12e853449063a0e0a724e704b4a (2认同)

Tho*_*olf 8

TLDR; Flux#doOnNext用于副作用, Flux#map用于将某些内容同步地从一种类型映射到另一种类型。

如果我们查看文档,它会说以下内容doOnNext

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

这意味着在 中doOnNext,我们可以做副作用,比如日志,或者在某处做一个休息调用等等。我们还返回一个 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.
Run Code Online (Sandbox Code Playgroud)

我们可以读到这里我们可以应用一个同步函数,基本上我们可以对我们发出的值做一些事情。添加一些东西,减去一些东西,以某种方式改变它,在这里我们可以将它转化为map其他东西。

如果我们查看 中的类型map,我们可以看到它map会发出一些东西,super T但它会返回一些extends V

这是一个典型的 Java 泛型模式,如果您想了解更多关于此的信息,我建议您观看Joshua Blochs 谈论泛型。整个视频很好看,会比我更好地解释它。

但我想指出的是,通过使用地图,您将返回不同的类型。你super T从通量中得到一些东西,然后你将它映射到其他东西extends V