一、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的更多相关文章

  1. 怎样在RxJS Observable中使用Async-Await

    怎样在RxJS Observable中使用Async-Await 一般情况下 async-await 和 Observables 并不能“在一起使用”.但RxJS 从一开始就具备与 Promises ...

  2. [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 ...

  3. [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 ...

  4. [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 ...

  5. 简单模拟实现Rxjs Observable

    1.先定义类型 export type Observer = { next: (any) => void, complete?: (any) => void, } export inter ...

  6. Angular 4+ Http

    HTTP: 使应用能够对远端服务器发起相应的Http调用: 你要知道: HttpModule并不是Angular的核心模块,它是Angualr用来进行Web访问的一种可选方式,并位于一个名叫@angu ...

  7. Angular基础(八) Observable & RxJS

    对于一个应用来说,获取数据的方法可以有很多,比如:Ajax, Websockets, LocalStorage, Indexdb, Service Workers,但是如何整合多种数据源.如何避免BU ...

  8. RxJS之Subject主题 ( Angular环境 )

    一 Subject主题 Subject是Observable的子类.- Subject是多播的,允许将值多播给多个观察者.普通的 Observable 是单播的. 在 Subject 的内部,subs ...

  9. RxJS - Subject(转)

    Observer Pattern 观察者模式定义 观察者模式又叫发布订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态 ...

随机推荐

  1. WIKI 部署后记录

    使用说明 环境 MYSQL 安装方式: YUM 版本:5.7 账号: root / 123456 主机白名单: localhost 账号:admin / 123456 主机白名单: % 账号:conf ...

  2. request 获取body内容

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException ...

  3. C++ 黑白棋AI minimax+alphabeta剪枝

    没事写着玩玩,通过debian上的黑白棋测试,搜了10层,打hard应该问题不大 #include <cstdio> #include <cstring> using name ...

  4. laravel 读写分离源码解析

    前言:上一篇我们说了<laravel 配置MySQL读写分离>,这次我们说下,laravel的底层代码是怎样实现读写分离的.   一.实现原理 说明: 1.根据 database.php ...

  5. 2019 年 3 月 iOS程序员面试心得总结,请大家多多指教!

    序言: 今年2月中下旬因为个人原因,换了一份工作,3月初期间面试了有3,4家,基本都是D轮或者刚刚上市的公司,也有上榜的BAT,也从他们的面试笔试中看到了自己的一些不足,于是就想写出来和大家分享一下, ...

  6. EF Code First一对一、一对多、多对多关联关系配置

    1.EF Code First一对一关联关系 项目结构图: 实体类: Account.cs using System; using System.Collections.Generic; using ...

  7. UNIX域协议之描述符传递

    一.mycat程序 #include <fcntl.h> #include <stdlib.h> #include <unistd.h> #define BUFFS ...

  8. arcgis图层 GraphicsLayer与FeatureLayer

    什么是图层 图层是用来在 ArcGIS 产品套件中显示地理数据集的机制.每个图层代表一种数据集(可以是地图服务.图形或是矢量数据),并指定该数据集是如何描绘使用一组属性的. 包含一个地图控件的每个应用 ...

  9. git体验

    (1)git初始化配置#配置用户名git config --global user.name "azcode"#配置邮箱git config --global user.email ...

  10. CSS3 Background-origin

    Background-origin是CSS3为Background扩展的第三个属性,从Background-origin字面上不难发现是指背景图片的原点,其实background-origin主要就是 ...