通俗理解RxJS(一)

自学 Rx 快有一个周了, 它非常适合处理复杂的异步场景。结合自己所学,决定写系列教程。

我认为, Rx 中强大的地方在于两处

  • 管道思想,通过管道,我们订阅了数据的来源,并在数据源更新时响应 。
  • 强大的操作符,通过操作符对流和流中的数据转换,拼接,以形成我们想要的数据模型 。

数据管道

在 Rx 中,我们先预装好管道,通过管道流通数据 。这些管道的来源多种, create ,from, fromEvent, of .., 通过操作符将管道 拼接,合并,映射...形成最终的数据模型 。
对于管道来说,有两点非常重要

  • . 管道是懒执行的,只有订阅器 observer subscribe了 数据管道,这个管道才会有数据流通 。
  • . 整个节点组成一个完整的管道,订阅了后面的管道节点,也会同时订阅之前的管道节点 ,每个节点接受之前的值,并发出新值。

在很多教程中, Rx 往往以这个例子开始 :

  const example = Rx.Observable.create ((observer) => {
    const timer = setTimeout(() => {
      observer.next(8);
    })
    observer.next(10);
    return () => {
      clearTimeout(timer);
    }
  })

  const unsubscribe = example.subscribe((a) => {
    console.log(a);
  })

  //结果当然是 10, 8.

这个例子发现了两种相似的设计模式

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

迭代器模式:类似于 JS 6 增加的迭代器 。

  const iterator = [1, 2, 3][Symbol.iterator]();
  while(true) {
    const result = iterator.next();
    if(result.done) return;

    cnosole.log(result.value);
  }

观察者模式: 事件模型是最常见的观察者模式, 定义生产者与消费者,生产者发出值,消费者收到消息,并执行相应行文 。 Observable 与其不同的是, Observable 是拉模型,懒执行,只有指定订阅者,生产者才会派发。 Rx 中的推模型实现Subject 就是采用观察者模式,不管有没有订阅者,都会推送数据 。

操作符

Rx 如此高效和强大,得益于其强大的操作符 。
主要包含下面几类

  • 创建操作符: create, range, of, from, fromEvent, fromPromise, empty ..
  • 组合 contact ,merge, startWith, zip ..
  • 时间 delay , throttle, dobounceTime, interval ..
  • 过滤: filter, first, last, skip, distinct, take ..
  • 转换: buffer,map, mapTo, mergeMap, switch, switchMap, reduce, scan ..
  • 工具: do, toPromise ..

vs Promise

很多大牛介绍,在相对简单的情况下,大可不必使用 Observable ,Promise 足以应对。
类似于下面的模型

  new Promise ((resolve, reject) = {})
  .then()
  .then()
  .then() ...

这种模型非常大程度改善了 回调地狱, 也能处理大部分的异步场景,name 对于 Rx , 它有哪些地方不足呢 ?

  • Rx 抽象了数据的来源,主要是对事件和网络请求的抽象 。
  • Rx 可以多次发出数据, 而Promise 只能发出一次数据, 复用之前的管道。
  • Rx 可以是懒执行的,只有在订阅之后,才会发出值,也就是订阅 。 而Promise 在定义后理解执行 。
  • 注意到我们上面的例子,是可以cancle 取消订阅的。
  return () => {
        clearTimeout(timer);
      }
    })

    const unsubscribe = example.subscribe((a) => {
      console.log(a);
    })

create 会返回一直函数,这个函数用于清理管道执行产生的垃圾,比如这里的定时器 。调用 unsubscribe 会取消订阅,并执行清理函数。

  • Promise 中数据变换只有通过then 链来进行,这点在fetch API 中体现最明显。但是Rx包含大量的操作符,简化了很多运算 。

尾声

在这一篇, 我介绍了Rx 的概念,以及与Promise 的对比,理解Rx ,主要是理解管道思想和响应式编程 。说Rx 门槛高,也就是新手们管道思想和响应式编程在前端的实践不多。
在下一篇,会分类使用所有的操作符,如果算是API 文档,那就死文档吧 。

posted @ 2017-10-13 15:25  小精灵儿Pawn  Views(700)  Comments(0Edit  收藏  举报

如果您觉得此文有帮助,可以打赏点钱给我支付宝。 谢谢 -):