RxJs——subject理解一

选中文字可对指定文章内容进行评论啦,绿色背景文字可以点击查看评论额。

什么是subject

首先我们来理解什么是subject,按照官方的定义:

A Subject is a special type of Observable that allows values to be multicasted to many Observers.

Subjects are like EventEmitters.

从定义我们看出subject就是一种允许发送值到多个观察者的特殊类型的Observable。它很像事件发送器。

我们分解一下,在结合网络上的一些分析,看看从定义中可以看出啥?

网络定义

A Subject is both an Observable and an Observer that allows values to be multicasted to many Observers, unlike Observables, where each subscriber owns an independent execution of the Observable.

subject继承了Observable,同时它也是一个Observer,允许值被广播到多个观察者,不同于Observable有单独的执行环境,它应该没有单独的执行环境。

这些意味着什么呢?我认为有三点:

1、你可以订阅主題从它的流中拉取值。

2、你可以推送值到流通过调用它的next方法,记住,它也是Observer

3、你可以把subject当做observer传递到一个Observable

图表说明

代码举例

const subject$ = new Subject<number>();

const observer = {
    next: console.log
}

const observable$ = interval(1000);

setTimeout(() => {
    console.log("Subscribing first observer");    
    subject$.subscribe(observer);
}, 1000);
        
setTimeout(() => {
    console.log("Subscribing second observer");
    subject$.subscribe(observer);
}, 2000);
        
observable$.subscribe(subject$);

日志信息

可以看出第一个订阅者订阅后我们的observable$发出了0;一秒后增加了第二个订阅者,observable$发出1以后直接广播到了两个observer,所以打印出了两个1,后面的情况类似。

subject内部特点

1、每次一个新的observer订阅,这个subject会将此observer存储在一个observber数组中。

2、当新的值发出时(比如调用next方法),subject将循环observer数组,发送相同的值到这些observer,这就是广播,当出现错误或者complete时,也会同样循环发送错误或complete。

3、当一个subject完成时,所有的observer数组中的observer取消订阅。

4、当subject取消订阅时,订阅依旧是激活的;但是所有的观察者数组将无效,但它不会取消订阅。如果你尝试發一个值,那么将发生错误;所以当你需要处理subject或者它的观察者时,最好直接完成它。

5、当subject的观察者取消订阅时,它将从sbject的注册数组中移除。

 

单播和多播

单播简单理解就是发送值到一个指定的观察者,而多播就是能够发送值到多个观察者。这里有一个重要的概念就是Cold Observable和Hot Observable。这些知识我们以后有机会再分析。

需要指出的是,今天我们谈论的主体其实就是将单播Observable转化成了多播Observable。

再举一个多播的例子吧。

多播的情况发生在订阅执行 HTTP 请求的 observable,这种情况在 Angular 等框架中经常发生:通过多播 observable,您可以避免执行多个请求并与多个订阅者共享执行,这些订阅者将接收相同的值。

 

其他类型的subject:AsyncSubject, ReplaySubject, and BehaviorSubject

AsyncSubject特点

1、仅仅在完成时发送值

2、仅仅发送出它接受到的最后一个值

图表说明

代码举例

onst asyncSubject$ = new AsyncSubject();
asyncSubject$.next(1);
asyncSubject$.next(2);
asyncSubject$.next(3);
asyncSubject$.subscribe(console.log);
console.log('after subscribe nothing');
// ... nothing happening!
asyncSubject$.complete();

日志信息

可以看出,订阅以后吗,没有发出值,一直到完成后才发出值。

其他两种我们下次分析,欢迎讨论。

版权声明:著作权归作者所有。

相关推荐

理解Java 9的open module(公开模块)

模块化是Java 9新增的一个很重要且影响代码结构的特性。分类根据外部代码在编译时和运行时对模块的访问权限不同分为:常规模块(normal module)和公开模块(open module)。编译时访问比较容易理解,即代码能否显式直接使用模块里的类型,没有权限访问,编译时报错。在运行时访问模块代码是指使用Java里的Core Reflection 

理解Java的数字溢出

Java各个数字类型所占的存储空间:整型byte:1字节,1*8bit,取值范围-128~127short:2字节,2*8bit,取值范围-32768~32767int:4字节,4*8bit,取值范围-2147483648~2147483647long:8字节,8*8bit,取值访问-2^64~2^64-1浮点型float:4字节,4*8bitdouble:8字节,8*8bitchar类型java

Kotlin使用kotlin-kapt插件支持Android的注解处理

在Kotlin可以使用kapt插件来支持Android的注解处理。在Gradle配置kotlin-kapt插件如下:在app的build.gradle添加插件apply plugin: 'kotlin-kapt' 使用kapt添加注解依赖java使用annotationProcessor 添加的依赖改为使用kapt。例如添加dagger依赖dependencies {

理解JavaScript普通函数以及箭头函数里使用的this

this普通函数的this普通函数的this是由动态作用域决定,它总指向于它的直接调用者。具体可以分为以下四项:this总是指向它的直接调用者, 例如 obj.func() ,那么func()里的this指的是obj。在默认情况(非严格模式,未使用 'use strict'),如果函数没有直接调用者,this为window在严格模式下,如果函数没有

Rxjs expand的用法分析

Rxjs的expand()函数声明:public expand(project: function(value: T, index: number), concurrent: number, scheduler: Scheduler): Observable expand()会递归调用project函数,project函数把源值映射为一个Observable,每次递归

理解React Native的Props和State

Props和State是React Native分别用来控制组件中两种不同类型的数据。Propsprops是Properties的简写,称为属性。props的特点是在组件内它是不可变,或者说不能被修改。在React数据流是单向的,从父组件到子组件的方向传递。props就是组件从父组件接收的数据,在组件内部是不能对它修改。props不可变的特性是有助于我们写可复用的组件。我们只需要对一个组

理解RxJava里Observables的相关类型

Observable — Operator — ObserverObservable,可观察者,它就好像扬声器一样,做一些处理后发射出一些值。Operator,操作符,它就像翻译员那样将数据从一种形式翻译/修改为另一种形式。Observer,观察者,它获得那些由可观察者发射出来的或者有操作符转译的值。它们的关系如图: RxJava可观察类型在RxJava的可观察类型如下

git bash配置代理解决下载慢的方法

首先找到一个代理服务地址,也可以使用shadowsocks,蓝灯。假设本地使用了蓝灯,http(s)代理地址为:127.0.0.1:52427。Git配置代理>git config http.proxy http://127.0.1:52427 >git config https.proxy https://127.0.1:52427Git设置为全局代理git config --glo

pandas给DataFrame一行一行添加数据

使用pandas的DataFrame有个 简单的功能,先定义pandas的DataFrame,然后按行给DataFrame添加数据。方法一:使用df.loc方法>>> import pandas as pd>>> from numpy.random import randint>>> df = pd.DataFrame(columns=['li

理解CKEditor5的schema

我们知道,CKEditor5是一个用MVC架构设计的富文本编辑器。如上图所示,三层分别是:Model,Controller, View首先,第一个问题是schema属于那一层?经过官方文档的初步学习,我们可以看到:editor.model.schema; // -> The model's schema.因此,我们可以得出结论:schema属于模型层:其次我们需

JPA实体状态深入理解

我们在学习JPA实体状态的时候,常常会问,JPA的实体有多少状态呢?相信这个问题不难回答:瞬时态(transient)托管态(persistent)游离态(detached)移除态(removed)注意:这里最后一个移除态,有的时候也叫删除态(deleted),至于它和移除态有啥区别,暂时没有想到,如果您对此有更加深刻的理解,请留言回复。为什么会有这四种状态呢?啥,这个也有为啥,网上不是都这么说的

CKEditor5——模型理解(一)

我们知道,CK5实现了一个MVC的架构,从今天开始,我们一步一步深入学习模型,视图,以及模型和视图之间的转换。今天我们开始模型的学习。首先,我们看模型的定义:The model is implemented by a DOM-like tree structure of elements and text nodes.模型由两类节点构成,分别是元素节点和文本节点,模型是一种类Dom树结构。我们知道

CKEditor5——模型理解(二:Node)

上一节我们理解了基本的CK5的模型基本信息,今天我们来学习一些模型的API。节点说明首先,需要理解的就是模型的节点。在这一点上,CK5的模型节点和dom的节点有点类似,也有一些不同。我会在文章中一一介绍。节点是模型树的基本结构。它是模型中不同节点类型的一种抽象。这里需要指出的一点是:如果一个节点从模型树中分离出来,你可以使用它的 API 来操作它。但是,非常重要的是,已经附加到模型树的节点只能通过

CKEditor5——模型理解(三:Element Text)

在上一节,我们学习了CK5中模型节点Node的API,今天我们学习另一个常用的API:Element。元素节点说明element表示模型的元素节点类型,它包含一个拥有名称和子节点的节点类型,继承自Node类。元素属性说明1、name,元素的名称举个例子哈,段落的名称是paragraph,代码块的名称是codeBlock等等。2、childCount, 子元素的数目这里指的是此元素节点包含的子元素的

javascript——generator理解

最近在学习CK5的时候,遇到了一个函数:function* _getAllUpcastDefinitions( definition ) { if ( definition.model.values ) { for ( const value of definition.model.values ) { const model = { key: definition.model.key

CKEditor5——模型理解(五:Position, Range, Selection)

今天我们继续学习CK5中模型的一些知识,主要包括:Position, Range, Selection首先,我们需要知道:position表示模型树中的一个位置。模型的位置有两部分组成:root,path。即位置由其根和该根中的路径表示。位置基于偏移量,而不是索引。这意味着两个文本节点 foo 和 bar 之间的位置偏移为 3,而不是 1。由于模型中的位置由位置根和位置路径表示,因此可以创建不存在

CKEditor5——模型理解(六:Range)

上一节我们主要介绍了模型中的Position这个关键的类,今天我们开始学习Range这个类。简单来说的话,如果Position表示一个点的话,那么Range是不是可以理解为一条线段呢?这个线段有一个startPostion,endPosition以及线段的长度等属性,我们暂且这么认为,那么我们可以看看Range官方的文档。从文档中看到,Range类有五个属性:Range属性start:Positi

CKEditor5——模型理解(七:Selection)

昨天我们学习了Range的一些API使用,今天我们看看另一个重要的类Selection的API:Selection的作用是记录鼠标在文档上的选择区域,如果是单个用户在编辑一份文档的时候,选择应该就是一个Range,如果是多个用户在编辑一份文档的时候,那么选择的区域就应该是多个range。因此,我大胆的猜测,Selection中应该有Range数组。我们来看看吧。Selection属性anchor

CKEditor5——Utils(工具类理解)

如果对CK5的代码有所理解的话,大概知道,CK5有一个非常重要的工具包项目,这个工具包非常重要,提供了CK5最基础的一些功能。比如:集合类Collection、事件类EmitterMixin、观察者类ObservableMixin等。今天我们暂缓学些以上的类,主要理解一个关于dom的类,那就是Position和Rect类,因为这两个类是CK5中弹出balloon工具条的基础类。我会一点点学习它的原