初识RxJS


        RxJS是Reactive Extensions for JavaScript 的缩写,起源于Reactive Extensions (他的目标是对异步的集合进行操作,也就是说,集合中的元素是异步填充的,比如说从Web或者云端获取数据然后对集合进行填充 ),是一个基于可观察数据流Stream结合观察者模式迭代器模式的一种异步编程的应用库RxJS是Reactive Extensions在JavaScript上的实现。

基于以上的定义,先来讲一下以下几个概念:

1. 响应式编程(RP --- Reactive Programming)

      响应式编程是一种面向数据流和变化传播的编程范式。在编程语言中很方便的表达静态或动态的数据流,而相关的计算模型会自动将变化的值通过数据流进行传播。
    (1)响应式编程是使用异步数据流编程。常见的异步数据流包括Event buses。用包含这些事件在内的任何东西创建数据流(Data Stream),监听它并作出响应;
    (2)只关注业务逻辑相互依赖的事件而不是实现细节;
    (3)适用于大量和数据有关的事件交互,特别是高实时性要求。

2. 流

(1) 一个流就是不间断的按照时间排序的序列。它产生三种不同类型事件:值、错误、完成的信号,对这三个定义事件处理函数,就可以异步的捕获这些事件。

(2)每个stream有多个方法,调用时会基于原来的流返回一个新的流,原来的流不做修改,保证不可变性。
(3) 数据流支持链式调用,可以组合不同的函数来处理流,创建和过滤不同的流。甚至一个流或多个流可以作为另一个流的输入。可以合并两个流。可以过滤一个数据流,从中获取一个包含你感兴趣的事件的数据流。可以将来自一个数据流的值映射到零一个数据流。

3. 观察者模式 Observer Mode(发布-订阅模式)

例子:
       购房者和售房部之间的信息订阅。购房者订阅售房部的房价信息,售房部维护一张需要信息的客户表,当有信息时,遍历表给符合条件的购房者推送发布房屋信息。这里,购房者担任观察者的角色,售房部是被观察的角色,当售房部信息发生变化,则自动推送信息给购房者。
结论:
       流(售房部/rxjs的Observable)是被观察的,当某个函数订阅流的某个事件(推送房价),该函数是观察者(购房者/rxjs的Observer)。当流的某个事件产生了,对应的函数就会被执行。

4. 迭代器模式

提供一种方法顺序访问一个聚合对象中的各个元素,而不需要暴露该对象的内部表示。最常见的就是JS中像Array、Set等这些内置的可迭代类型,可以通过iterator方法来获取一个迭代对象,调用迭代对象的next方法获取一个元素对象。

var iterable = [1, 2];
var iterator = iterable[Symbol.iterator]();
iterator.next(); // => { value: "1", done: false}
iterator.next(); // => { value: "2", done: false}
iterator.next(); // => { value: undefined, done: true}

JS的Iterator只有一个next方法,这个next方法只会回传以上两种结果。iterator通过调用next获取值,是一种pull数据的形式。 

与Promise的区别

let p = new Promise((resolve, reject) => {
    doAsyncThing((err,value) => {
     if(err){
       reject(err)
     } else {
      resolve(value)
     }
  })
})
--------------------------------------------
let o = new Observer (observer => {
   doAsyncThing((err,value) => {
    if(err){
       observer.error(err)
    } else {
    observer.next(value);
    observer.complete();
   }
 })
})

(1)Promise本质上也是一个Observable,能使fromPromise把Promise转成Observable;
(2)Promise.then只能返回一个值,Observable可以返回多个值;
(3)Promise要么reject要么resolve,并且只响应一次。而Observable可以响应多次。
(4)Promise不能取消,Observable可以调用unsubscribe()取消订阅。

5. Observable - 被观察者

      RxJS是观察者模式+迭代器模式的结合,Observable作为被观察者,是一个可调用的未来值或事件的集合。就像是一个序列,里面的元素会随着时间推送。

// 通过create方法创建一个Observable,回调函数会接受observer
var observable = Observable.create(function(observer){
  observer.next('hi');  
  observer.next('world');

setTimeout(() => {
    console.log('这是一段异步操作');
  },30);
})

console.log('start');

// 订阅这个observable,只有在订阅之后才会在流Observable变化的时候,
// 调用observer提供的方法,并通知他;
// 订阅之后也可以取消订阅,调用unsubscribe()即可
var subscription = observable.subscribe(function(value) => {
 console.log(value);
})

console.log('end');

setTimeout(() => {
 subscription.unscuscribe();
 console.log('取消订阅');
},5000)

结果: 

 所以,Observable不同于观察者模式中的被观察者,他没有一份需要维护订阅者的清单,他只是一个函数。想要订阅他只需要传进回调函数observer就好。并且Observable可以同时处理同步和异步操作。常见的创建Observable的方法如下:

创建Observable的方式 具体API

单值 

of,empty,never
多值 from所有可枚举的参数
定时 interval,timer
从事件创建 fromEvent  例如:
Rx.Observable.formEvent(document.body, 'click')
从Promise创建 fromPromise
自定义创建 create

6. Observer - 观察者 

       代表一个用来接收观察结果的对象(收到的就是事件资料);观察者就是一个对象包含3个含有回调函数的属性(next、error、complete)

和迭代器模式一一对应,提供三个方法:next、error、complete
var Observer = {
   next(value) { /*处理值*/ },
   error(error){ /*处理异常*/ }
   complete () { /*处理已完成态*/ }
};
next():接收Observable发出的值(必传)
error():不同于迭代器里面的try、catch,Observer用error方法接收错误(可选)
complete():当没有数据发出的时候,触发操作(可选)

7. Subscription - 订阅

建立在观察者和被观察者之间的观察关系。/ 代表正在执行Observable/Observable的执行个体。

       Observable产生一个可观察对象,通过Observer去观察它,这整件事是一个Subscription; 通过Observable丢出来的这些数据(data / stream),到被订阅 (订阅实际上是个callback函数 )真正的拿到data,这一段过程可以想象成一个水管(管道),所以我的水进入到水管,可以通过过滤、转换、映射的方法把这些data进行处理,最后拿给观察者。所以,operator就是Observable到Observer的过程中过滤这些data的一种运算符(操作工具)。


 8. Operator - 操作符

操作Observable的函数就是操作符。他会接受传入的Observable,但是会返回新的Observable。
用map举例说明:

Rx.Observable.of(2)
             .map(v => v*2)
             .subscribe(v =>console.log('output': + v));
// output: 4

常用的操作符有:

数据流操作 API
单个数据流 改变数据形态 map、mapTo
过滤 filter、skip、first、last、take
操作时间轴

delay、timeout、throttle、debounce、audit、bufferTime

累加

scan
异常处理 throw、catch
条件执行 takeUntil、delayWhen、ObserveOn
多个数据流 合并 concat、merge、combineLatest、withLatestFrom、zip

9. Subject - 主体对象/主体物件

       如同EventEmitter一样,主要用来广播收到的事件资料给多位Observer。将Obverser的定向派送转成广播派送。

例子:
① 建立主体对象(Subject)(之后要靠主体对象进行传播):
   var subject = new rxjs.Subject();

② 建立可观察的Observer对象:
    var clicks$ = rxjs.formEvent(document,  ' click ');

③ 设定最多取得两件个事件资料就将Observable对象设为完成:
    clicks$ = clicks$.pipe(take(2));

④ 设定将clicks$ 全部交由 subject 主体对象进行广播(订阅):
     clicks$.subscribe(subject)

⑤ 最后再由subject去建立Observer观察者对象(subject充当观察者observer):
     var subs1$ = subject.subscribe((x) => console.log(x.clientX))
     var subs2$ = subject.subscribe((x) => console.log(x.clientX))

⑥ 取消订阅Subscription对象
     subs1$.unscribe();       
     subs2$.unscribe();

       所以这里如果是clicks$多次订阅subscribe 和 利用主体物件subject 进行广播有什么区别呢?广播的话pipe不会重复执行,直接订阅的话会重复执行pipe。

(Observable 定义一个Subscription,Observer通过Subscription去订阅Observable,所以可以通过Subscription取消订阅,Operators在Observer拿到数据前,对数据进行处理,Subject 针对同一个Observable 被多个Observer多次订阅进行统一数据传递

10. Schedulers - 排程控制器

用来集中管理与调度多重事件之间的资料,以控制事件并发情况。、

大家主要记住5-9这五个概念
产生Observable   通过pipeAPI传入operator  通过subscribe传入Observer  subscribe会返回subscription  

猜你喜欢

转载自blog.csdn.net/m0_52545254/article/details/126957815