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),它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态 ...
随机推荐
- EOF输入
EOF是一个计算机术语,为End Of File的缩写,在操作系统中表示资料源无更多的资料可读取.资料源通常称为档案或串流.通常在文本的最后存在此字符表示资料结束.是int类型的宏定义,它扩展为负整数 ...
- python实现猜字游戏
import randomx = random.randint(0,99)while(True): num = input("please input a number\n") i ...
- 背包问题(01背包,完全背包,多重背包(朴素算法&&二进制优化))
写在前面:我是一只蒟蒻~~~ 今天我们要讲讲动态规划中~~最最最最最~~~~简单~~的背包问题 1. 首先,我们先介绍一下 01背包 大家先看一下这道01背包的问题 题目 有m件物品和一个容量为 ...
- 利用GitHub Pages和Bootstrap创建个人网站
作为一名想要想找前端实习的即将毕业的学生,我最近意识到拥有个人网页会使自己的简历更容易被注意到.本文主要是我创建过程及个人心得,有些操作我也是第一次,所以难免在解释中会有错误.另外说明一下,我的电脑是 ...
- 一个网站SQL注入的案例
网站的页面提交参数做了md5转换,而且参数会带入两个SQL语句中执行. 注入是肯定存在的,但是SQLMAP怎么都跑不出来(可能原因是其中有个SQL语句总是报错). 尝试手工,发现 order by 报 ...
- 《模式分类(原书第二版)》pdf格式下载电子书免费下载
<模式分类(原书第二版)>pdf格式下载电子书免费下载: https://u253469.ctfile.com/fs/253469-302448505 内容简介 <模式分类>( ...
- Asp.net Core导出Excel
本篇文章是在MVC设计模式下,基于windows系统的Excel导出 1.前台的实现不用我多说了吧,加一个a标签链接地址跳到它所调用的方法里面,可以根据当前页面的查询条件去传值,从而查询出你想要的数据 ...
- day 23-1 类的命名空间、组合
类的命名空间 类与对象命名空间 类里 可以定义两种属性 静态属性 动态属性 类中的静态变量 可以被对象和类调用对于不可变数据类型来说,类变量最好用类名操作对于可变数据类型来说,对象名的修改是共享的,重 ...
- EOCS框架概述和剖析
什么是EOCS? EOCS(Enterprise Operation Cross System),是一个基于eosio底层框架实现的企业级跨链操作系统,旨在实现和EOS主链通信的并行链,是真正意义的跨 ...
- ddt源码修改:HtmlTestRunner报告依据接口名显示用例名字
背景是这样的: 自己写了一套接口自动化的框架,其中使用unittest + ddt + excel作为数据驱动模式的应用,使用HtmlTetstRunner来生成测试用例. 一切看起来很完美. 但是, ...