在Spring WebFlux中,then、thenEmpty、thenMany和flatMapMany是什么?

41
我不理解在Spring WebFlux中的FluxMono上使用thenthenEmptythenManyflatMapMany的用途和区别。

3
我在Project Reactor文档中找到了答案。https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html - Amr Khaled
有趣的是,这个“问题”获得了30个赞,实际上并不是一个问题 :) 1+ - Eugene
1个回答

75
  • flatMap vs flatMapMany

在函数式编程中,flatMap 返回与拥有该方法的类型相同的类型,因此对于 Mono<T>flatMap 返回一个 Mono。这意味着内部 Publisher 只能发出一个元素(或被截断)。我们通过使 Mono#flatMap 接受一个 Function<T, Mono<R>> 来强制执行这一点。

因此,我们需要一种替代方案来处理任意可以发出多个元素的 Publisher。因此有了 Mono#flatMapMany(Function<T, Publisher<R>>),它返回一个 Flux<R>

简而言之:Mono#flatMap 用于源 Mono 中元素的异步但一对一转换,Mono#flatMapMany 用于一对多的异步转换(如 Flux#flatMap)。

  • thenthenEmptythenMany

Mono 上的所有 thenXXX 方法都有一个共同的语义:它们忽略源 onNext 信号,并在完成信号(onCompleteonError)上做出反应,以各种选项继续该序列。因此,这可能会更改返回的 Mono 的通用类型:

  1. then 只会重放源终端信号,导致 Mono<Void> 表示从不发出任何 onNext
  2. thenEmpty 不仅返回一个 Mono<Void>,而且它将一个 Mono<Void> 作为参数。它表示源完成信号后接着第二个“空” Mono 完成信号。换句话说,当 A 然后 B 顺序完成时,它就完成了,并且不会发出数据。
  3. thenMany 等待源完成,然后播放其 Publisher<R> 参数的所有信号,导致一个 Flux<R>,该流将“暂停”,直到源完成,然后从提供的发布者中发出多个元素,最后重放其完成信号。

我正在使用 thenMany 来在 guard 后继续执行。这是一种好的模式吗?即,如果前置条件失败,则 guard 会返回 Mono.error(...),否则返回 Mono.empty()。然后我使用 thenMany 继续计算并在我的 WebFlux 应用中返回 Flux - wilmol
是的,@wilmol,那应该可以工作,尽管我想Mono.errorflatMap内部使用(你称之为“guard”)?如果是这样,在flatmap的else分支中直接返回Flux比从thenMany返回更少的开销。 - Simon Baslé
请注意,即使其中任何一个抛出错误,“then” Mono 的所有内容都将被订阅,而“map”的不会。 - Gonzalo
https://intojava.wordpress.com/2020/11/25/difference-between-flatmap-and-flatmapmany-in-webflux/ - Hariom Yadav

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