Skip to content

《深入浅出RxJS》笔记-RxJS入门 #22

Description

@isNeilLin

chapter2-RxJS入门

1

/** 导入方式** - import语法导入* import Rx from 'rxjs'; * * - commonJS风格的require函数 * const Rx = require('rxjs');**/

上面的两种写法是一样的效果,但上面的导入写法会将整个RxJS库都导入进来,会让打包文件较大。
解决这个问题可以使用深链(deep link)的方式,只导入用上的功能。比如要使用Observable类:

importObservablefrom'rxjs/Observable';

或者使用CommonJS风格的require函数:

constObservable=require('rxjs/Observable').Observable;

RxJS的架构设计决定了Tree-Shaking无法对其起作用。RxJS的大部分功能都是围绕Observable类而创建的,而且这些功能都体现为Observable这个类的一个函数,有的是类函数,有的是成员函数,这些函数都是要‘挂’到Observable这个类上去。换句话说,这些函数不管我们的应用代码用还是不用,在RxJS内部都已经被Observable类‘引用’了,被引用知乎,Tree-Shaking就不会觉得这些函数是“枯枝”,也就会在打包文件中保留下来。

2
RxJS中的数据流就是Observable对象,每个Observable对象代表的就是在一段时间内发生的一系列事件。Observable实现了下面来两种设计模式:

  • 观察者模式
  • 迭代器模式

Observable可以用下面这种公式表示:Observable = Publisher + Iterator

import{Observable}from'rxjs/Observable';constonSubscribe=observer=>{observer.next(1);observer.next(2);consttimer=setTimeout(()=>{clearTimeout(timer);observer.next(3);observer.complete();},1000)}constsource$=newObservable(onSubscribe);consttheObserver={next: item=>console.log(item),error: (err)=>console.log(err),complete: ()=>console.log("No More Data")}source$.subscribe(theObserver);/** * 1、函数onSubscribe会被用作Observable构造函数的参数,这个函数参数完全决定了Observable对象的行为。onSubscribe函数接受一个名为observer的参数,函数体内,调用参数observer的next函数,把数据推给observer。* 2、调用Observable构造函数产生一个名为source$的数据流对象* 3、创造观察者theObserver* 4、通过subscribe(订阅)函数将theObserver和source$关联起来**/

创建Observable对象就是创建了一个“发布者”,Observable的subscribe函数被调用之后对应的onSubscribe函数就会被调用,参数就是观察者对象,上例中观察者就是theObserver。onSubscribe函数中可以任意操作观察者对象。这个过程就等于在这个Observable对象上挂上了号,以后当这个Observable对象产生数据时,观察者就会获得通知。

Observer对象的complete函数和error函数何时被调用,完全看Observable对象的行为,和数据一样,完结信号和错误信号也是由Observable推给Observer的

3
为了让代码更简洁,没有必要创造一个Observer对象,subscribe也可以直接接收函数作为参数,第一个参数如果是函数类型,就被认为是next,第二个参数如果是函数类型,就被认为是error,第三个参数被认为是complete。

source$.subscribe(item=>console.log(item),err=>console.log(err),()=>console.log("No More Data"));

如果不关心不关心异常的处理,但是关心Observable的终止事件,那依然要传递第二个参数来占位置,可以传递null,表示不处理异常事件。

上面的例子中onSubscribe函数并没有返回任何结果,其实onSubscribe函数可以返回一个对象,对象上可以有一个unsubscribe函数。代表的就是和subscribe“订阅”相反的动作,也就是退订。

constonSubscribe=observer=>{observer.next(1);observer.next(2);consttimer=setTimeout(()=>{clearTimeout(timer);observer.next(3);observer.complete();},1000)return{unsubscribe: ()=>{}}}

unsubscribe函数调用之后,作为Observer不再接受到被推送的数据。但是作为Observable的source$在没有调用complete或者errror的情况下不会终结,只不过它再也不会调用next函数了。这是RxJS中很重要的一点:Observable产生的事件,只有Observer通过subscribe订阅之后才会收到,在unsubscribe之后就不会再收到

4
Hot Observable: 只接受从订阅那一刻开始Observable产生的数据
Cold Observable: 在subscribe之前Observable产生的数据也要获取

每一个Cold Observable概念上都可以理解成对每一次subscribe都产生一个“生产者”,然后这个生产者产生的数据通过next函数传递给订阅的Observer。上面的Observable对象source$是Cold Observable,因为每次通过subscribe函数添加一个Observer,这个Observable对象都会直接调用参数的next函数传递固定的数据。可以认为固定的数据就是一个简单的“生产者”。

而对于Hot Observable,概念上是有一个独立于Observable对象的“生产者”,这个“生产者”的创建和subscribe调用没有关系,subscribe调用只是让Observer连接上“生产者”而已。

Cold Observable和Hot Observable的概念代码

// Cold Observableconstcold$=newObservable(observer=>{constproducer=newProducer();// 然后让observer去接受producer产生的数据})// Hot Observableconstproducer=newProducer();consthot$=newObservable(observer=>{// 然后让observer去接受producer产生的数据})

在Hot Observable中,Observable明显并不产生数据,只是数据的搬运工。

Metadata

Metadata

Assignees

No one assigned

    Labels

    框架&工具库Vue和React等前端框架或工具库相关

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions