简体   繁体   English

如何在 Project Reactor 中将 Mono 多播给多个订阅者?

[英]How to multicast a Mono to multiple subscribers in Project Reactor?

With what I have read so far, one can multicast a Flux to multiple subscribers using ConnectableFlux using something similar to following:根据我到目前为止所读到的内容,可以使用类似于以下内容的ConnectableFlux将 Flux 多播给多个订阅者:

Flux<Integer> integerFlux = Flux.range(1, 50)
                .log();

ConnectableFlux<Integer> integerConnectableFlux = integerFlux.publish();

integerConnectableFlux.map(i -> i*2)
                .subscribe(System.out::println);

integerConnectableFlux.map(i -> i*3)
                .subscribe(System.out::println);

integerConnectableFlux.connect();

To my limited understanding of reactive streams, above code converts a cold publisher to a hot publisher.我对反应式流的理解有限,上面的代码将冷发布者转换为热发布者。 I am working on scenario where I have multiple subscribers for a Mono .我正在处理一个Mono有多个订阅者的场景。 How can I get a hot publisher out of a Mono?如何从 Mono 中获得热门出版商?

Have a look at Mono#cache() operator:看看Mono#cache()运算符:

Turn this Mono into a hot source and cache last emitted signals for further Subscriber.将此 Mono 转换为热源并缓存最后发出的信号以供进一步的订阅者使用。 Completion and Error will also be replayed.完成和错误也将重播。

Managed to multicast the mono using Mono.share() operator:使用Mono.share()运算符管理多播单声道:

Prepare a Mono which shares this Mono result similar to Flux.shareNext().准备一个 Mono,它类似于 Flux.shareNext() 共享此 Mono 结果。 This will effectively turn this Mono into a hot task when the first Subscriber subscribes using subscribe() API.当第一个订阅者使用 subscribe() API 订阅时,这将有效地将这个 Mono 变成一个热门任务。 Further Subscriber will share the same Subscription and therefore the same result.其他订阅者将共享相同的订阅并因此获得相同的结果。 It's worth noting this is an un-cancellable Subscription.值得注意的是,这是一个不可取消的订阅。

Example: Following code creates only one subscription on the publisher:示例:以下代码仅在发布者上创建一个订阅:

        Mono<Integer> integerMono = Mono.just(2)
                .log()
                .share();

        integerMono.map(i -> i+3)
                .subscribe(System.out::println);

        integerMono.map(i -> i*5)
                .subscribe(System.out::println);

Output of above code is shown below (data is requested only once):上面代码的输出如下所示(数据只请求一次):

5
reactor.Mono.Just.1 - {} - | onSubscribe([Synchronous Fuseable] Operators.ScalarSubscription)
reactor.Mono.Just.1 - {} - | request(unbounded)
reactor.Mono.Just.1 - {} - | onNext(2)
reactor.Mono.Just.1 - {} - | onComplete()
10

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM