WebFlux响应式编程中如何二次处理数据并访问上游变量
问题解决方法
链式map操作每一步的入参仅保留上一步的返回值,所以第二步map无法直接访问第一步生成的dataA,根据你用的是普通Stream流还是响应式编程(Reactor/RxJava),选以下方案即可:
方案1:嵌套作用域访问(最推荐,代码最简洁)
把需要用到dataA的后续操作,放到生成dataA的操作符作用域内部,天然就能访问到变量:
- 如果是响应式编程(
serviceA.doSomething()返回Mono/Flux),用flatMap处理返回响应式类型的serviceB调用:
serviceA.doSomething() .flatMap(dataA -> serviceB.doSth(dataA) // 内部闭包可直接访问dataA .map(dataB -> serviceC.doSth(dataA, dataB)) )
- 如果是普通Java Stream,直接在同一个map块里完成两步操作即可,不需要拆成两次map:
sourceList.stream() .map(dataA -> { DataB dataB = serviceB.doSth(dataA); return serviceC.doSth(dataA, dataB); })
方案2:透传多值(适合长链路多次访问前置变量的场景)
如果后续链路很长,嵌套会导致代码层级过深,可以在第一步把需要复用的dataA和新生成的dataB封装在一起往下传:
- Java 16+ 推荐用record做封装,可读性最好:
// 先定义简单的不可变数据载体 record DataPair(DataA a, DataB b) {} serviceA.doSomething() .flatMap(dataA -> serviceB.doSth(dataA).map(dataB -> new DataPair(dataA, dataB))) .map(pair -> serviceC.doSth(pair.a(), pair.b()))
- 如果是Reactor环境也可以直接用内置的
Tuples工具类,不需要额外定义类:
serviceA.doSomething() .flatMap(dataA -> serviceB.doSth(dataA).map(dataB -> Tuples.of(dataA, dataB))) .map(tuple -> serviceC.doSth(tuple.getT1(), tuple.getT2()))
不推荐的写法
不要试图在链式调用外部定义可变局部变量缓存dataA:响应式编程是延迟执行的,异步场景下这类外部可变变量很容易出现值错乱、空指针问题,bug排查成本极高。
内容的提问来源于stack exchange,提问作者Elva
相关产品推荐
相关产品推荐

