我跑了这个
Mono<Void> mono = Mono.empty();
System.out.println("mono.block: " + mono.block());
它会产生:
mono.block: null
符合预期。换句话说,如果block
已经完成,则调用Mono
将立即返回。
另一个例子,类似于真实场景。我有一个源通量,例如:
Flux<Integer> ints = Flux.range(0, 2);
我创建了一个可连接的流量,用于允许多个订阅者:
ConnectableFlux<Integer> publish = ints.publish();
在此示例中,假设有一个实际工作的订户:
publish
.doOnComplete(() -> System.out.println("publish completed"))
.subscribe();
和另一个只生成元素计数的订户:
Mono<Long> countMono = publish
.doOnComplete(() -> System.out.println("countMono completed"))
.count();
countMono.subscribe();
我连接可连接的助焊剂并打印元素计数:
publish.connect();
System.out.println("block");
long count = countMono.block();
System.out.println("count: " + count);
此打印:
publish completed
countMono completed
block
换句话说,两个订户都成功订阅并完成订阅,但随后countMono.block()
被无限期阻止。
为什么会这样,我该如何做呢?我的最终目标是获取元素的数量。
答案 0 :(得分:1)
您可以使用autoConnect
或refCount
来代替手动调用connect()
。
例如:
Flux<Integer> ints = Flux.range(0, 2);
Flux<Integer> publish = ints.publish()
.autoConnect(2); // new
publish
.doOnComplete(() -> System.out.println("publish completed"))
.subscribe();
Mono<Long> countMono = publish
.doOnComplete(() -> System.out.println("countMono completed"))
.count();
// countMono.subscribe();
long count = countMono.block();
System.out.println("count: " + count);
这是我认为您的示例中正在发生的事情...但这是基于我的有限知识,我不确定100%正确。
.publish()
将上游源转化为热流.connect()
订阅上游并开始流程connect()
之前完成注册的两个订阅(因为这都是在主线程中发生的)block()
创建一个 new 订阅。connect()
(由于主线程被阻塞,则从另一个线程调用),数据将再次流动,并且block()
将完成。但是,这将是一个 new 序列(而不是在步骤4中完成的原始序列)仅创建两个订阅(而不是示例中的3个),一个来自.subscribe()
调用,一个来自.block()
。 2个订阅后,ConnectableFlux自动连接,因此block()
订阅完成。这两个订阅共享相同的上游序列。