• 初识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方法获取一个元素对象。

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

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

    与Promise的区别

    1. let p = new Promise((resolve, reject) => {
    2. doAsyncThing((err,value) => {
    3. if(err){
    4. reject(err)
    5. } else {
    6. resolve(value)
    7. }
    8. })
    9. })
    10. --------------------------------------------
    11. let o = new Observer (observer => {
    12. doAsyncThing((err,value) => {
    13. if(err){
    14. observer.error(err)
    15. } else {
    16. observer.next(value);
    17. observer.complete();
    18. }
    19. })
    20. })

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

    5. Observable - 被观察者

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

    1. // 通过create方法创建一个Observable,回调函数会接受observer
    2. var observable = Observable.create(function(observer){
    3. observer.next('hi');
    4. observer.next('world');
    5. setTimeout(() => {
    6. console.log('这是一段异步操作');
    7. },30);
    8. })
    9. console.log('start');
    10. // 订阅这个observable,只有在订阅之后才会在流Observable变化的时候,
    11. // 调用observer提供的方法,并通知他;
    12. // 订阅之后也可以取消订阅,调用unsubscribe()即可
    13. var subscription = observable.subscribe(function(value) => {
    14. console.log(value);
    15. })
    16. console.log('end');
    17. setTimeout(() => {
    18. subscription.unscuscribe();
    19. console.log('取消订阅');
    20. },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举例说明:

    1. Rx.Observable.of(2)
    2. .map(v => v*2)
    3. .subscribe(v =>console.log('output': + v));
    4. // 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  

  • 相关阅读:
    Ubuntu 添加 GitLab 官方仓库报错“curl is unable to connect to packagecloud.io over TLS”
    代码随想录57——动态规划:647回文子串、516最长回文子序列
    (面试题)面试官为啥总是让我们手撕call、apply、bind?
    基本排序算法的总结笔记
    Blender关键帧动画简明教程
    无线通信的未来:WiFi HaLow的低功耗、超长距离革命
    漏洞复现--IP-guard flexpaper RCE
    web3调研:Iron fish调研
    spark案例分析-搜索引擎日志分析案例
    vue3网页将表格内容导出到excel
  • 原文地址:https://blog.csdn.net/m0_52545254/article/details/126957815