Project Reactor中blockLast()工作原理及执行顺序疑惑
为什么Reactor中blockLast()没有让上游先发射所有元素再处理下游?
你误解了blockLast()的作用和Reactor的核心执行模型:
blockLast()的本质:它只是在调用线程(这里是main线程)上阻塞,直到整个Flux的所有元素都处理完成(包括下游的所有操作),最终返回最后一个元素。但它不会改变Reactor流式处理的逻辑——元素依然是逐个从上游传递到下游,而不是先批量生成所有元素再统一处理。Reactor的流式处理逻辑:默认情况下,Reactor是背压驱动的同步流式处理。以你的代码为例:
Flux.range(0,1000)每生成一个元素,就会立刻传递给doOnNext执行打印;- 这个元素接着进入
flatMap(默认并行度为1,串行处理),执行end的打印; - 当下游处理完这个元素的所有逻辑后,才会向上游请求下一个元素,所以就出现了
i和end交替输出的情况。
subscribe()和blockLast()的一致性:
subscribe()只是触发流式处理但不阻塞主线程,blockLast()是触发处理并阻塞直到完成,两者的核心处理流程完全一致,所以输出自然相同。
如果你想实现**先打印所有i,再打印所有end**的效果,可以通过collectList()先把上游所有元素收集到一个List中,再展开处理,这样就能让上游先完成所有元素的发射,再统一处理下游逻辑:
Flux.range(0, 1000) .doOnNext(i -> System.out.println("i = " + i + " Thread: " + Thread.currentThread().getName())) .collectList() // 收集所有元素到List,等待上游完成 .flatMapIterable(list -> list) // 将List重新展开为Flux .flatMap(i -> { System.out.println("end" + i + " Thread: " + Thread.currentThread().getName()); return Mono.just(i); }) .blockLast();
这段代码中,collectList()会让上游把0到999的所有元素都生成并收集完毕,之后才会把整个List传递给下游,这时下游才会逐个处理每个元素,最终实现你预期的输出顺序。
内容的提问来源于stack exchange,提问作者BoredPanda
相关产品推荐
相关产品推荐

