RXJS Observable的冷,热和Subject
一、Observable的冷和热

Observable 热:直播。所有的观察者,无论进来的早还是晚,看到的是同样内容的同样进度,订阅的时候得到的都是最新时刻发送的值。
Observable 冷:点播。 新的订阅者每次从头开始。
冷的Observable例子:
一开始有个订阅者,
两秒后又有个订阅者,这两个序列按照自己的节奏走的,不同步。每个流进行都会从interval的0开始。
console.log('RxJS included?', !!Rx);
const count$ = Rx.Observable.interval().take();
const sub1 = count$.subscribe((val)=>{
console.log(val);
});
setTimeout(function(){
const sub2 = count$.subscribe((val)=>{
console.log(val);
});
},);

热的Observable例子
第二个订阅者直接从2开始起,跟第一个订阅者看到的内容是一样的。
const count$ = Rx.Observable.interval(1000).take(5).share();
const sub1 = count$.subscribe((val)=>{
console.log(val);
}); setTimeout(function(){
const sub2 = count$.subscribe((val)=>{
console.log(val);
});
},2000);

二、Subject

Subject即是观察者Observer,也是被观察对象Observable,同时实现了这两个接口。
意味着
- 一方面它可以作为流的组成的一方,输出的一方。
- 另一方面,它可以作为流的观察一方,接收一方。
Subject分为ReplaySubject和BehaviorSubject。
ReplaySubject:这种Subject会保留最新的n个值。
BehaviorSubject:是ReplaySubject的特殊形式。 保留最新的一个值。
【20200529】
拿subject做一个observer观察者,看Observable会丢什么东西出来,由它对外广播出去。
再拿subject去订阅两个观察者。
有n个observable去订阅subject,但是subject只会发出一个订阅的要求订阅原始observable。
1、subscribe的等价写法
subscribe 后面写的一个函数,相当于语法糖,快捷方式,临时创建冷一个observer对象。
默认情况应该是传入一个observer对象。
console.log('RxJS included?', !!Rx);
const counter$ = Rx.Observable.interval(1000).take(5);
const subject = new Rx.Subject();
const observer1 = {
next: (val)=>{console.log('1: ' +val);},
error: (err)=>{console.log('ERROR>> 1:'+ err);},
complete: ()=>{console.log('1 is complete');}
}
const observer2 = {
next: (val)=>{console.log('2: ' +val);},
error: (err)=>{console.log('ERROR>> 2:'+ err);},
complete: ()=>{console.log('2 is complete');}
}
//等价写法
counter$.subscribe(val =>{console.log(val);});
counter$.subscribe(observer2);

2、两个observer ,两次subscribe
console.log('RxJS included?', !!Rx);
const counter$ = Rx.Observable.interval(1000).take(5);
const subject = new Rx.Subject();
const observer1 = {
next: (val)=>{console.log('1: ' +val);},
error: (err)=>{console.log('ERROR>> 1:'+ err);},
complete: ()=>{console.log('1 is complete');}
}
const observer2 = {
next: (val)=>{console.log('2: ' +val);},
error: (err)=>{console.log('ERROR>> 2:'+ err);},
complete: ()=>{console.log('2 is complete');}
}
counter$.subscribe(observer1);
setTimeout(function(){
counter$.subscribe(observer2);
},2000);

问题:需要在两处执行subscribe,很多情况下是这样的,定义好这些序列应该在什么时候被触发,我执行执行一句subscribe(),两个序列都会这么执行。这种情况下就需要用subject()。
3、subject
subject即使observable,因为它可以subscribe observer。
也是observer,因为它可以被observable subscribe。
console.log('RxJS included?', !!Rx);
const counter$ = Rx.Observable.interval(1000).take(5);
const subject = new Rx.Subject();
const observer1 = {
next: (val)=>{console.log('1: ' +val);},
error: (err)=>{console.log('ERROR>> 1:'+ err);},
complete: ()=>{console.log('1 is complete');}
}
const observer2 = {
next: (val)=>{console.log('2: ' +val);},
error: (err)=>{console.log('ERROR>> 2:'+ err);},
complete: ()=>{console.log('2 is complete');}
}
//不再用counter$去subscribe,用subject去subscribe,
subject.subscribe(observer1);
setTimeout(function(){
subject.subscribe(observer2);
},2000);
//定义好两边后,用counter$去subscribe
counter$.subscribe(subject);

用一句执行counter$.subscribe(subject),把定义好的序列,包括等待2秒的序列全部完成了。
4,subject是一个hot observable
往流里推送新值

第二个拿不到新值,因为第二个流订阅的时候,两个新值已经过去了。

5,ReplaySubject
replay把过去发生的事件进行重播。
ReplaySubject(2)把过去的2个事件进行重播。这样observer1 subscribe的时候就可以看到10和11。

6、BehaviorSubject只记住最新的值
总有一个最新值,总记住上一次的最新值
console.log('RxJS included?', !!Rx);
const counter$ = Rx.Observable.interval(1000).take(5);
const subject = new Rx.BehaviorSubject();
subject.next(10);
subject.next(11);
const observer1 = {
next: (val)=>{console.log('1: ' +val);},
error: (err)=>{console.log('ERROR>> 1:'+ err);},
complete: ()=>{console.log('1 is complete');}
}
const observer2 = {
next: (val)=>{console.log('2: ' +val);},
error: (err)=>{console.log('ERROR>> 2:'+ err);},
complete: ()=>{console.log('2 is complete');}
}
//不再用counter$去subscribe,用subject去subscribe,
subject.subscribe(observer1);
setTimeout(function(){
subject.subscribe(observer2);
},2000);
//定义好两边后,用counter$去subscribe
counter$.subscribe(subject);

取值的时候,会取得到最新的data,尽管在取值的时候也就是subscribre的时候值已经发射完了,尽管时机已经错失了还是能够得到它上一次发射之后的最新的一个值。
三、Angular中对Rx的支持
大量内置Observable支持:如Http,ReactiveForms,Route等。
Async Pipe是什么?有什么用?
Observable需要subscribe 一下,成员数组变量等于Observable得到的值。
使用Async Pipe可以直接使用Observable,还不用去取消订阅。

memberResults$: Observable<User[]>;

本文作者starof,因知识本身在变化,作者也在不断学习成长,文章内容也不定时更新,为避免误导读者,方便追根溯源,请诸位转载注明出处:https://www.cnblogs.com/starof/p/10505617.html 有问题欢迎与我讨论,共同进步。
RXJS Observable的冷,热和Subject的更多相关文章
- 怎样在RxJS Observable中使用Async-Await
怎样在RxJS Observable中使用Async-Await 一般情况下 async-await 和 Observables 并不能“在一起使用”.但RxJS 从一开始就具备与 Promises ...
- [RxJS] Split an RxJS Observable into groups with groupBy
groupBy() is another RxJS operator to create higher order observables. In this lesson we will learn ...
- [RxJS] Split an RxJS observable conditionally with windowToggle
There are variants of the window operator that allow you to split RxJS observables in different ways ...
- [RxJS] Split an RxJS observable with window
Mapping the values of an observable to many inner observables is not the only way to create a higher ...
- 简单模拟实现Rxjs Observable
1.先定义类型 export type Observer = { next: (any) => void, complete?: (any) => void, } export inter ...
- Angular 4+ Http
HTTP: 使应用能够对远端服务器发起相应的Http调用: 你要知道: HttpModule并不是Angular的核心模块,它是Angualr用来进行Web访问的一种可选方式,并位于一个名叫@angu ...
- Angular基础(八) Observable & RxJS
对于一个应用来说,获取数据的方法可以有很多,比如:Ajax, Websockets, LocalStorage, Indexdb, Service Workers,但是如何整合多种数据源.如何避免BU ...
- RxJS之Subject主题 ( Angular环境 )
一 Subject主题 Subject是Observable的子类.- Subject是多播的,允许将值多播给多个观察者.普通的 Observable 是单播的. 在 Subject 的内部,subs ...
- RxJS - Subject(转)
Observer Pattern 观察者模式定义 观察者模式又叫发布订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态 ...
随机推荐
- 51nod1237 最大公约数之和
题目链接 题意 其实就是求 \[\sum\limits_{i=1}^n\sum\limits_{j=1}^ngcd(i,j)\] 思路 建议先看一下此题的一个弱化版 推一下式子 \[\sum\limi ...
- JS基础知识(未完)
学习笔记,知识点来源于掘金小册-yck-前端面试之道 1.原始类型(6种) 原始类型储存的都是值 number boolean string null undefined symbol null不是对 ...
- Vue(小案例_vue+axios仿手机app)_Vuex优化购物车功能
一.前言 1.用vuex实现加入购物车操作 2.购物车详情页面 3.点击删除按钮,删除购物详情页面里的对应商品 二.主要内容 1.用vuex加入购物车 (1)在src ...
- 1. Ansible 简介
目录 1. Ansible 是什么? 2. Ansible 特性 3. 控制主机需求 4. 被管理节点需求 1. Ansible 是什么? Ansible 是一个配置管理系统(configuratio ...
- CentOS命令登录MySQL时,报错ERROR 1045 (28000): Access denied for user root@localhost (using password: NO)错误解决方法
1.停用mysql服务:# /etc/rc.d/init.d/mysqld stop 2.输入命令:# mysqld_safe --user=mysql --skip-grant-tables --s ...
- Spring缓存注解@Cacheable
@Cacheable @Cacheable 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存 @Cacheable 作用和配置方法 参数 解释 example value 缓存的名称, ...
- qml layout
一.使用总结 1.锚点:锚点锚在父控件左边anchors.left: parent.left ,才可以设置anchors.leftMargin:20 才有作用,设置anchors.topMargin: ...
- [HTTP]POST报文中Content-Type对正文解析的影响
概述 在POST请求中,理论上请求端程序可以发送任意格式报文正文,但是最好在报文头Content-Type字段标明正文的格式,方便接收端根据Content-Type正确处理正文. 传统HTML-for ...
- 奇yin技巧
关于一些奇yin技巧 关于删除字符串中的一些字串,并且考虑新的字串 例题:luogu4824 luogu3121 方法:开一个栈记录,发现字串后剪去字串长度. for(int i=1;i<=le ...
- hbase学习一 shell命令操作
基本操作: #命名空间级别: #列出所有命名空间 hbase> list_namespace #新建命名空间 hbase> create_namespace 'ns1' #删除命名空间 h ...