Java 在发布程序完成之前触发时
示例代码:Java 在发布程序完成之前触发时,java,project-reactor,Java,Project Reactor,示例代码: 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
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");
为什么它不等待两个发布者(fluxA
和monoB
)完成呢?我应该如何构造代码,以确保在到达之后的之前完成所有发布程序?通过使用.publish()
,fluxSrc
变成热通量。考虑:
另一方面,热门出版商并不依赖于任何数量的
订户。他们可能会立即开始发布数据,并且
每当新订户进来时,继续这样做(在这种情况下
所述订户将只看到在其之后发射的新元素
订阅)。对于热门出版商来说,以前确实发生过一些事情
你订阅
()
解决这个问题的一种方法是摆脱publish
,在冷流上运行。另一种是更改.autoConnect(2)代码>到自动连接(3)代码>-这是因为您希望在第三次订阅时开始处理数据-Mono.when(fluxA,monoB.block()代码>已到达(前面的是fluxA.subscribe
和monoB.subscribe
)
编辑:
当
确实在等待震源完成时,但它从先前的细分中得到了一个完整的信号
可能发生的情况是:
通量A被fluxA.subscribe(System.out::println)所替代代码>,发出11并打印它
通量B被monoB.subscribe(System.out::println)所替代代码>并开始还原
Mono。当
被录制时(触发“多播”——流量被第二次录制)
开始减少,结果将是21
另一个减少开始并立即完成,结果为20(减少fluxSrc中的空流-仅项目已被另一个减少消耗)
向两个订阅方发送一个完整的通量
通量B发送完成,还原结果=20。它被传递到Mono制作的订阅。当
时,这就是它没有被打印的原因
自Mono.when subscription以来,两种通量均未完成发送,因此打印后
大约在那个时候,第一次缩减完成,值为21,传递给monoB.subscribe(System.out::println)代码>
因此,fluxSrc
是一个热门流量,可能在订阅block
之前发布。你能解释一下为什么当不等待fluxA
和monoB
完成时,这会导致?这是因为比赛条件。如果您只是希望将“after”作为最后一条语句打印,那么必须同步reactor调度器和应用程序的线程。此外,一旦完成信号被广播到每个用户,在我的机器上,它看起来是这样的:完成通量a;完成单声道b;完成的通量仍然不能解释为什么当不等待两个源完成时。反应流不是完全为了用户不必担心线程和竞争条件而生成的吗?让程序在执行线程时表现出不同的行为。在之前睡眠当时并不真正令人鼓舞。不确定从何处获得步骤4和步骤8-减少会产生单声道
,因此它不能发射两次monoB
最多会发出一个结果,它必须在完成之前发出,对吗?事实上,B必须在还原后完成-我更正了顺序。初始值为20,当前值为1的Mono的减少产生21,并完成Mono。将已完成的fluxSrc(Mono B的基础)的初始值减少为20会产生20。这意味着,在这种情况下,MonoB将只发射一个项目,但由于多个订阅方的多播,该多播项目的减少结果将有所不同。
11
After
21