Webflux中repeat方法结合不同操作符的执行行为疑问
Reactor中repeat操作符对执行顺序的影响逻辑
Reactor的repeat操作符核心行为非常明确:它会让自己上游的整个数据流分支重复执行指定次数(初始执行1次 + 重复n次,共n+1次),而下游操作符的执行时机,完全取决于它们和repeat、以及其他操作符的相对位置。
下面结合你的测试场景逐一拆解:
场景1:repeat位于所有doOnNext之后
Mono.just(5) .doOnNext(i -> System.out.println("next 1: " + i)) .doOnNext(i -> System.out.println("next 2: " + i)) .doOnNext(i -> System.out.println("next 3: " + i)) .repeat(2) .subscribe();
输出:
next 1: 5 next 2: 5 next 3: 5 next 1: 5 next 2: 5 next 3: 5 next 1: 5 next 2: 5 next 3: 5
这里repeat的上游是包含三个doOnNext的完整数据流,所以整个上游分支会重复执行3次,每次都按顺序触发三个doOnNext,结果符合预期。
场景2:repeat位于第一个doOnNext之后,其余doOnNext在repeat下游
Mono.just(5) .doOnNext(i -> System.out.println("next 1: " + i)) .repeat(2) .doOnNext(i -> System.out.println("next 2: " + i)) .doOnNext(i -> System.out.println("next 3: " + i)) .subscribe();
输出和场景1完全一致,原因是:repeat每次重新订阅上游的Mono.just(5).doOnNext(1)分支,发射的数据5都会流过repeat,触发下游的doOnNext(2)和doOnNext(3)。也就是说,每次循环都是next1 → next2 → next3,重复3次,所以最终输出和场景1无差别。
场景3:repeat位于then操作符之后
Mono.just(5) .doOnNext(i -> System.out.println("next 1: " + i)) .doOnNext(i -> System.out.println("next 2: " + i)) .then(Mono.just("hello")) .doOnNext(i -> System.out.println("next 3: " + i)) .repeat(2) .subscribe();
输出:
next 1: 5 next 2: 5 next 3: hello next 1: 5 next 2: 5 next 3: hello next 1: 5 next 2: 5 next 3: hello
repeat的上游是包含then的完整数据流:每次执行时,先完成Mono.just(5)的两个doOnNext,再通过then切换到Mono.just("hello")触发next3,整个分支重复3次,所以输出符合预期。
场景4:repeat位于第一个doOnNext之后,then在repeat下游
Mono.just(5) .doOnNext(i -> System.out.println("next 1: " + i)) .repeat(2) .doOnNext(i -> System.out.println("next 2: " + i)) .then(Mono.just("hello")) .doOnNext(i -> System.out.println("next 3: " + i)) .subscribe();
输出:
next 1: 5 next 2: 5 next 1: 5 next 2: 5 next 1: 5 next 2: 5 next 3: hello
这里的关键是then属于终止型操作符:它会等待当前数据流分支完全完成后,才会切换到后续的Mono.just("hello")。而repeat让上游的Mono.just(5).doOnNext(1)重复执行3次,每次执行都会触发下游的doOnNext(2);只有当这3次循环全部完成后,then才会执行,触发一次next3。这就是你看到顺序变化的核心原因。
总结:repeat影响顺序的场景划分
- 不会影响顺序的场景:当
repeat的下游是doOnNext、map、filter这类非终止型操作符时,每次repeat完成一次上游订阅,都会将数据传递给下游操作符,最终表现为「上游单次逻辑 → 下游逻辑」重复N次,和repeat在最末尾的顺序效果一致。 - 会影响顺序的场景:当
repeat的下游存在then、and、when这类终止型操作符时,这些操作符会等待repeat上游的所有重复循环全部完成后,才会执行后续逻辑,最终表现为「上游循环N次 → 下游终止型操作符及其后续逻辑执行1次」。
内容的提问来源于stack exchange,提问作者opoa
相关产品推荐
相关产品推荐

