当前位置: 首页 > article >正文

Project Reactor中 map、flatMap、concatMap 和 flatMapSequential 的区别

Project Reactor(Reactive Streams 的实现库,常用于 Spring WebFlux)中,mapflatMapconcatMapflatMapSequential 是常用的操作符,但它们的功能和行为有显著区别。以下是它们的详细对比:


1. 功能对比

操作符功能描述输入类型输出类型顺序性并发性
map同步转换元素元素(T元素(R保持顺序无并发
flatMap异步转换元素为 Publisher,并发处理所有 Publisher元素(TPublisher(Publisher<R>不保证顺序并发
concatMap异步转换元素为 Publisher,按顺序处理 Publisher元素(TPublisher(Publisher<R>保持顺序无并发
flatMapSequential异步转换元素为 Publisher,并发处理 Publisher,但按顺序发射结果元素(TPublisher(Publisher<R>保持顺序并发

2. 行为对比

map
  • 作用:将 Flux 或 Mono 中的每个元素同步转换为另一个元素。
  • 特点
    • 同步操作。
    • 不改变流的类型(例如,Flux 仍然是 Flux,Mono 仍然是 Mono)。
  • 示例
    Flux<Integer> flux = Flux.just(1, 2, 3);
    flux.map(value -> value * 10)
        .subscribe(System.out::println);
    
    输出
    10
    20
    30
    
flatMap
  • 作用:将 Flux 或 Mono 中的每个元素异步转换为一个 Publisher(如 Flux 或 Mono),并并发处理这些 Publisher。
  • 特点
    • 异步操作。
    • 改变流的类型(例如,将 Flux 转换为另一个 Flux)。
    • 不保证顺序。
  • 示例
    Flux<Integer> flux = Flux.just(1, 2, 3);
    flux.flatMap(value -> 
        Mono.just(value * 10).delayElement(Duration.ofMillis(100)) // 异步转换
    ).subscribe(System.out::println);
    
    输出(可能无序):
    10
    20
    30
    
concatMap
  • 作用:将 Flux 或 Mono 中的每个元素异步转换为一个 Publisher(如 Flux 或 Mono),并按顺序连接这些 Publisher。
  • 特点
    • 异步操作。
    • 改变流的类型(例如,将 Flux 转换为另一个 Flux)。
    • 按顺序处理 Publisher。
  • 示例
    Flux<Integer> flux = Flux.just(1, 2, 3);
    flux.concatMap(value -> 
        Mono.just(value * 10).delayElement(Duration.ofMillis(100)) // 异步转换
    ).subscribe(System.out::println);
    
    输出
    10
    20
    30
    
flatMapSequential
  • 作用:将 Flux 或 Mono 中的每个元素异步转换为一个 Publisher(如 Flux 或 Mono),并发处理这些 Publisher,但按顺序发射结果。
  • 特点
    • 异步操作。
    • 改变流的类型(例如,将 Flux 转换为另一个 Flux)。
    • 并发处理,但按顺序发射结果。
  • 示例
    Flux<Integer> flux = Flux.just(1, 2, 3);
    flux.flatMapSequential(value -> 
        Mono.just(value * 10).delayElement(Duration.ofMillis(100)) // 异步转换
    ).subscribe(System.out::println);
    
    输出
    10
    20
    30
    

3. 适用场景

操作符适用场景
map简单的同步转换操作,例如将字符串转换为大写、将数字乘以某个值等。
flatMap需要并发处理的异步操作,且不关心顺序,例如并发请求多个外部服务。
concatMap需要异步操作且保持顺序的场景,例如按顺序插入数据库记录。
flatMapSequential需要并发处理但结果顺序重要的场景,例如并发请求多个外部服务但按顺序返回结果。

4. 性能与资源消耗

操作符性能与资源消耗
map同步操作,性能开销小。
flatMap异步操作,性能开销较大,适合高并发场景。
concatMap异步操作,性能开销较大,顺序性可能导致性能瓶颈。
flatMapSequential异步操作,性能开销较大,适合需要并发处理但结果顺序重要的场景。

总结

  • map:用于同步的元素转换,适合简单的数据处理。
  • flatMap:用于异步的元素转换,并发处理所有 Publisher,适合高并发场景。
  • concatMap:用于异步的元素转换,按顺序处理 Publisher,适合需要顺序性的场景。
  • flatMapSequential:用于异步的元素转换,并发处理 Publisher 但按顺序发射结果,适合需要并发处理且结果顺序重要的场景。

http://www.kler.cn/a/566658.html

相关文章:

  • 【Uniapp-Vue3】在uniapp中使用pinia的基本用法
  • 大模型系列——专家混合模型 (MoE)快速指南
  • Rk3568驱动开发_完善字符驱动_4
  • React学习笔记08
  • 【算法】MySQL算法
  • VSCode大的JSON数据不能折叠问题
  • LeetCode 滑动窗口章节 (持续更新中)
  • 复杂html动态页面高还原批量导出方案
  • 微服务即时通信系统---(六)语音识别子服务
  • 【Java】Spring Boot全量YAML配置说明
  • 爬虫获取 item_get 接口:获得VIP商品详情的完整指南
  • Java语言Leetcode中常用的一些基础语法
  • 性能测试测试策略制定|知名软件测评机构经验分享
  • 经典算法 统计数字问题(常数时间解决)
  • LeetCode 热门100题-除自身以外数组的乘积
  • 【原创】Ubuntu 24搭建Ollama+ DeepSeek局域网服务器
  • 不同Embedding模型与大语言模型(LLM)的交互主要通过语义向量传递实现
  • 对泰坦尼克号沉没事件幸存者数据分析和预测
  • 如何用python画一棵分形树
  • [C++] enum 以及 enum class 简单用法