[Day 15] Reactive Programming -Reactor(COLD VS HOT) -PART 2

前言

其实有一个特别的例子是just,直觉会认为just就是产生一个publisher等人来subscribe,理所当然就是Cold Publisher,我一开始也是这样认为,直到看到官方doc说明他是Hot Publisher,原来最熟悉的好朋友其实如此的陌生,又在程序的道路上学习了人生的一课,Cold Publisher是Lazy loading,但其实just在assembly time就已经准备好所有的data,当有Subscriber订阅只是在replay一次而已。

defer

使用Flux.just的时候,在assembly time就已经取得资料,我们可以改成透过defer,回归lazy,直到subscribe才会取资料,defer就是延迟的意思,透过Supplier来达到延迟的效果,来源资料会被延迟到subscribe才会被初始化,也是因为这样,如果来源资料是与当下时间有关,这样每个不同的subscribe都会取到不同的时间,但本质上还是一个Cold Publisher。
https://ithelp.ithome.com.tw/upload/images/20210929/20141418bTtz2GEQJA.png

以下范例是分别透过just & defer来取用现在时间,可以看出just每次subscribe结果会相同,就能得知just在assembly time就已经取资料了,而defer则是延迟直到subscribe才真的去取得现在时间,看到这边可以会有点错乱,原本以为Hot Publisher是每次结果会不相同,但这边的Hot Publisher是just 每次结果相同,COLD Publisher的defer则会每次不同,老实说我是有点错乱,官方文件上也没有明确定义cold & hot,所以我个人认为是产生资料的时间点,如果是lazy的要等到subscribe才会触发的就是COLD Publisher,如果无论有没有subscribe都会先取得资料的,则是Hot Publisher。

Mono<Long> clock = Mono.just(System.currentTimeMillis());
Mono<Long> clockDefer = Mono.defer(() -> Mono.just(System.currentTimeMillis()));

Thread.sleep(500);
clock.subscribe(t -> System.out.println("clock:"+ t));
clockDefer.subscribe(t -> System.out.println("\tclockDefer:"+ t));

Thread.sleep(500);
clock.subscribe(t -> System.out.println("clock:"+ t));
clockDefer.subscribe(t -> System.out.println("\tclockDefer:"+ t));
/*
clock:1631980808996 
	clockDefer:1631980809602 
clock:1631980808996 
	clockDefer:1631980810105 */

COLD VS HOT

再比较一次COLD 与HOT的不同,第一个范例是先用fromIterable产生一个cold publisher,两个Subscriber 得到的结果是一模一样的。

Flux<String> source =
    Flux.fromIterable(Arrays.asList("blue", "green", "orange", "purple"))
        .map(String::toUpperCase);

source.subscribe(d -> System.out.println("Subscriber 1: " + d));
source.subscribe(d -> System.out.println("Subscriber 2: " + d));
/*
Subscriber 1: BLUE
Subscriber 1: GREEN
Subscriber 1: ORANGE
Subscriber 1: PURPLE
Subscriber 2: BLUE
Subscriber 2: GREEN
Subscriber 2: ORANGE
Subscriber 2: PURPLE 
*/ 

https://ithelp.ithome.com.tw/upload/images/20210929/20141418I3G8q9pIUa.png

再来利用前面学到的Sinks动态的产生Flux,当时就有提到後面subscribe的只会得到之後的资料,可以看到Subscriber 2 就只有橘色与紫色。

Sinks.Many<String> hotSource = Sinks.unsafe().many().multicast().directBestEffort(); 
Flux<String> hotFlux = hotSource.asFlux().map(String::toUpperCase); 
hotFlux.subscribe(d -> System.out.println("Subscriber 1 to Hot Source: "+d)); 
hotSource.emitNext("blue", FAIL_FAST);  
hotSource.tryEmitNext("green").orThrow();  
hotFlux.subscribe(d -> System.out.println("Subscriber 2 to Hot Source: "+d)); 
hotSource.emitNext("orange", FAIL_FAST); 
hotSource.emitNext("purple", FAIL_FAST); 
hotSource.emitComplete(FAIL_FAST);
/*
Subscriber 1 to Hot Source: BLUE 
Subscriber 1 to Hot Source: GREEN 
Subscriber 1 to Hot Source: ORANGE 
Subscriber 2 to Hot Source: ORANGE 
Subscriber 1 to Hot Source: PURPLE 
Subscriber 2 to Hot Source: PURPLE
*/

https://ithelp.ithome.com.tw/upload/images/20210929/20141418SFJPEWncLj.png

结语

经过两天的学习,应该能大致了解cold/hot publihser,不过其实官方文件并没有明确定义,所以建议也不用太钻牛角尖的想去定义每一个operator是属於哪一种,遇到再来讨论。

图片来源

资料来源


<<:  Day14 Combine 01 - 简介

>>:  @Day29 | C# WixToolset + WPF 帅到不行的安装包 [如何拿已经安装好的资料]

Day22 - 【概念篇】Keycloak使用基本概念 - 前导

本系列文之後也会置於个人网站 在这之前,都是先请大家照着做,没有好好说明关於Keycloak的使用...

Day28:每天一个小练习 - JS30-13-Slide in on Scroll

参考资料: Alex老师教学 PJCHENder笔记 卷动出现图片。 题目预设的过滤效果,避免多次触...

模型架构--2

SphereFace 在2017年发表在CVPR的文章,改进原先使用softmax作为loss fu...

【Day 11】Button Template 应用 part 2

昨天原本要连同 Confirm buttom 一起讲的~,但平均一下每天的文章量,今天再接着讲另一个...

Day 13 懒得想变数吗? RSpec 有提供你啦

该文章同步发布於:我的部落格 还记得我们使用 let 方法来实作一个物件来让我们可以快速使用! 但...