如何正确使用Mono<Void>?按序执行后调用getDto的方案是否可行
你的实现方案核心正确,但需注意操作符的细节区别
你的代码逻辑是对的,能保证void1()→void2()→void3()→getDto()严格按顺序执行,因为then操作符的本质就是等待当前Mono完成后,再订阅执行下一个Mono,完全匹配你“先做数据准备,最后获取DTO”的需求。不过针对你注释里提到的几个替代操作符,需要明确它们的差异:
.then(void2())vsthenEmpty
两者效果完全一致,都能等待void1()完成后执行void2()。但thenEmpty的语义更清晰——它专门用于后续是Mono<Void>的场景,所以推荐用.thenEmpty(void2()),代码可读性更强。.then(void3())vsdoOnNext
绝对不能用doOnNext!doOnNext是副作用操作符,它不会改变流的执行顺序,也不会等待内部逻辑完成:- 如果你写
.doOnNext(__ -> void3().subscribe()),void3()会和后续的getDto()并行执行,破坏顺序; - 如果直接写
.doOnNext(__ -> void3()),void3()甚至不会被触发执行(因为Mono只有被订阅才会运行)。
这里必须用then或thenEmpty来保证顺序等待。
- 如果你写
.then(getDto())vsdoOnSuccess
也不能用doOnSuccess:doOnSuccess只是在当前流成功完成时执行副作用,不会等待副作用完成,也不会替换原流的返回值;- 用它的话,最终返回的还是前面的
Mono<Void>,而不是你需要的Mono<Dto>,而且getDto()可能根本不会被订阅执行。.then(getDto())才是正确选择——它会等待前面所有准备操作完成后,订阅getDto()并将其结果作为整个流的输出。
推荐写法
return void1() .thenEmpty(void2()) .thenEmpty(void3()) .then(getDto());
内容的提问来源于stack exchange,提问作者Aliaksei
相关产品推荐
相关产品推荐

