使用WebClient转换响应时FlatMap对比Map的优势及异步性疑问
问题解答
1. 方式1是否属于异步?
首先明确:方式1里的转换逻辑本身是同步的。
你这里用flatMap包裹的代码只是简单创建MyResponse对象、赋值字段,最后返回Mono.just(myResponse)——这整个过程是同步执行的,没有任何异步操作。
不过整个响应流的异步性来自上游的myutil.invokeWebClient(input),因为WebClient本身是异步非阻塞的,所以不管用flatMap还是map,整个请求处理链路都是异步非阻塞的,但flatMap里的转换步骤是同步的。
2. 仅提取响应字段转换为其他对象时,flatMap相对map的优势是什么?
这种场景下,flatMap没有任何优势,反而属于冗余用法。
map的设计初衷就是用来做同步的、无副作用的对象转换,正好匹配你现在“提取字段转成MyResponse”的需求,代码更简洁直接。flatMap的核心作用是处理返回Mono/Publisher的异步操作——比如你在转换过程中需要再调用另一个远程API、查询数据库这种异步任务时,才需要用flatMap来把嵌套的Mono“扁平化”成一个流。
现在你用flatMap只是把同步逻辑包成了Mono返回,完全是画蛇添足,还会增加不必要的Mono包装开销。
附上你提供的代码片段:
@PostMapping(value = "/test", produces = { "application/json" }) public ResponseEntity<Mono<MyResponse>> test(@RequestBody String input) { Mono<ThirdPartyResponse> response = myutil.invokeWebClient(input); //approach 1 final Mono<MyResponse> transformedResponse1 = response.flatMap(value -> { final MyResponse myResponse = new MyResponse(); myResponse.setAccountNumber(value.getRoot().getMsgOut().getAcctNbr()); return Mono.just(myResponse); }); //approach 2 final Mono<MyResponse> transformedResponse2 = response.map(value -> { final MyResponse myResponse = new MyResponse(); myResponse.setAccountNumber(value.getRoot().getMsgOut().getAcctNbr()); return myResponse; }); return ResponseEntity.status(HttpStatus.OK).body(transformedResponse1); }
内容的提问来源于stack exchange,提问作者Thiagarajan Ramanathan
相关产品推荐
相关产品推荐

