Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
isNeilLin opened this issue Oct 30, 2018 · 0 comments
Open

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

isNeilLin opened this issue Oct 30, 2018 · 0 comments
Labels
框架&工具库 Vue和React等前端框架或工具库相关

Comments

@isNeilLin
Copy link
Owner

chapter2-RxJS入门

1

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

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

import Observable from 'rxjs/Observable';

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

const Observable = 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';

const onSubscribe = observer => {
    observer.next(1);
    observer.next(2);
    const timer = setTimeout(()=>{
         clearTimeout(timer);
         observer.next(3);
         observer.complete();
    },1000)
}
const source$ = new Observable(onSubscribe);
const theObserver = {
    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“订阅”相反的动作,也就是退订。

const onSubscribe = observer => {
    observer.next(1);
    observer.next(2);
    const timer = 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 Observable
const cold$ = new Observable(observer => {
    const producer = new Producer();
    // 然后让observer去接受producer产生的数据
})

// Hot Observable
const producer = new Producer();
const hot$ = new Observable(observer => {
    // 然后让observer去接受producer产生的数据
})

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

@isNeilLin isNeilLin changed the title 《深入浅出RxJS》笔记 《深入浅出RxJS》笔记-RxJS入门 Oct 30, 2018
@isNeilLin isNeilLin added the RxJS label Oct 30, 2018
@isNeilLin isNeilLin added 框架&工具库 Vue和React等前端框架或工具库相关 and removed RxJS labels Jun 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
框架&工具库 Vue和React等前端框架或工具库相关
Projects
None yet
Development

No branches or pull requests

1 participant