示例代码:
Flux<Integer> fluxSrc = Flux.<Integer> create(e -> {
e.next(1);
try {
Thread.sleep(500);
} catch (InterruptedException e1) {
throw new RuntimeException(e1);
}
e.complete();
})
.publishOn(Schedulers.single())
.publish().autoConnect(2);
Flux<Integer> fluxA = fluxSrc
.publishOn(Schedulers.single())
.map(j -> 10 + j);
fluxA.subscribe(System.out::println);
Mono<Integer> monoB = fluxSrc
.publishOn(Schedulers.single())
.reduce(20, (j, k) -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
throw new RuntimeException(e1);
}
return j + k;
});
monoB.subscribe(System.out::println);
Mono.when(fluxA, monoB)
.block();
System.out.println("After");
这将产生以下输出:
11
After
21
为什么它不等待两个发布者(fluxA
和monoB
)都完成?我应该如何构造代码,以确保在到达After
之前所有发布者都已完成?
答案 0 :(得分:1)
通过使用.publish()
,fluxSrc
变成热通量。考虑:
另一方面,热门发布者不依赖任何数量的 订阅者。他们可能会立即开始发布数据,并且会 每当有新的订户进入时,都应继续这样做(在这种情况下) 表示订户只会看到它之后发出的新元素 已订阅)。对于热门发布者来说,确实确实发生了一些事 您订阅。
(https://projectreactor.io/docs/core/release/reference/#reactor.hotCold)
解决此问题的一种方法是摆脱publish
并在冷流下运行。另一种是将.autoConnect(2);
更改为.autoConnect(3);
-这是因为您要在第三个订阅时开始处理数据-达到Mono.when(fluxA, monoB).block();
(先前的是fluxA.subscribe
和{{1} }。
修改:
monoB.subscribe
确实等待源代码完成,但是它从先前的订阅中获得了onComplete信号。
可能发生的事情是:
When
所限制,发出11并打印出来。fluxA.subscribe(System.out::println);
所取代,并开始减少。monoB.subscribe(System.out::println);
被添加了(这触发了“多播”-流量被第二次添加了。)Mono.when
进行的订阅,这就是为什么它不被打印的原因。Mono.when
。After