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),它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态 ...
随机推荐
- Linux-文件管理
文件管理 创建.复制.删除.移动.查看.编辑.压缩.查找 Linux目录结构 Windows: 以多根的方式组织文件 C:\ D:\ E:\Linux: 以单根的方式组织文件 / /目录结构: FSH ...
- LOJ#2668 书法家
题意:要在一张网格纸上画出NOI图形,使得所占格子的权值和最大. 解:暴力DP即可... 从左往右,每个字母都可以被划分成三块,且每块都可用上下两维来表示. 于是一块一块的DP.考虑如何O(1)转移. ...
- CodeForces - 314C Sereja and Subsequences (树状数组+dp)
Sereja has a sequence that consists of n positive integers, a1, a2, ..., an. First Sereja took a pie ...
- mysql8.0.15二进制安装
mysql8.0.15二进制安装 今天有幸尝试安装了社区版本的mysql8.0.15,记录下来,供以后方便使用.特此感谢知数堂的叶老师,提供了配置文件的模板. # 第一部分:系统配置 # 1.安装系统 ...
- IP地址类型
为了适应不同的网络,IP地址空间被分为5类,分别是A.B.C.D和E类,其中A,B,C类最常用,D类用于组播,E类用于科研 IP地址类型 第一字节十进制范围 二进制固定最高位 二进制网络位 二进制主机 ...
- 2018-2019-2 实验二 Java面向对象程序设计
实验内容 1.初步掌握单元测试和TDD 2.理解并掌握面向对象三要素:封装.继承.多态 3.初步掌握UML建模 4.熟悉S.O.L.I.D原则 5.了解设计模式 实验要求 1.没有Linux基础的同学 ...
- java压缩文件或文件夹并导出
java压缩文件或文件夹并导出 tozipUtil: package com.zhl.push.Utils; import java.io.File; import java.io.FileInput ...
- Thunk
Thunk https://en.wikipedia.org/wiki/Thunk In computer programming, a thunk is a subroutine used to i ...
- 解决系统中大量的TIME_WAIT连接
今天发现网站特别卡!! 查看网络连接数: netstat -an |wc -l netstat -an |grep xx |wc -l 查看某个/特定ip的连接数 netstat -an ...
- Python实现身份证号码有效性验证
# -*- coding: utf-8 -*- import re #Errors=['验证通过!','身份证号码位数不对!','身份证号码出生日期超出范围或含有非法字符!','身份证号码校验错误!' ...