map 和 flatMap 在反应式Reactor中的区别 - map VS flatMap

map VS flatMap in Reactor

    • 一、同步非同步方法的区别
    • 二、处理发布者方式和返回类型的区别
    • 三、转换1到N的区别
    • 最后疑问:`map` 真的是同步且非阻塞的吗?️

一、同步非同步方法的区别

  • map 用于同步非阻塞的一对一转换
  • flatMap 适用于异步非阻塞的1到N转换

这两个区别在方法签名中可以发现:

英文原版:

  • map takes a Function and returns a Flux
  • flatMap takes a Function and returns a Flux

中文译文:

  • map 接受Function 并返回Flux
  • flatMap 接受Function 并返回Flux

二、处理发布者方式和返回类型的区别

我们可以将Function>传递给map,但map却不知道如何处理发布者。这也导致map 返回的一串不活动的发布者 Flux>

另一方面,flatMap 期望每个传来的 T 都有 Publisher flatMap 知道如何处理它:订阅它并在输出序列中传播其元素。
所以,flatmap最后总会返回 Flux 类型:flatMap将把每个内部Publisher 展平为所有V的输出序列。

三、转换1到N的区别

关于1到N转换方面:

对于每个输入元素 flatMap 会将其映射到 Publisher 。在某些情况下(例如HTTP请求),该发布者将仅发出一项,在这种情况下,我们非常接近异步的 map

但这是一种最简化的情况。通常情况下,发布者会发出多个元素,使用 faltmap 就可以比 map 有更为良好的运行效率。

例如,假设您有一个反应性数据库,flatmap从一系列用户ID,请求返回了每个用户的徽章 Set 集合。最后,flatmap 会返回一个包含所有用户的徽章集合的 Flux (因为会被压扁flatten)。

最后疑问:map 真的是同步且非阻塞的吗?️

答案是肯定的:操作符应用map 的方式是同步的(一个简单的方法调用,然后操作员发出结果),并且在操作符调用 map 时函数本身不会阻塞这个调用,从这个意义上说是 map 非阻塞的。换句话说,map 不应会引入延迟。这是因为Flux总体上还是异步的。如果阻塞了 Flux 的序列中某个元素,这将影响其余的 Flux 处理,甚至其他 Flux

如果你发现使用 map 函数时,会阻塞/引入延迟,但是无法转换并返回 Publisher 发布者,请考虑使用 publishOn / subscribeOn 来抵消在单独线程上的阻塞。

你可能感兴趣的:(java,reactor)