美文网首页
RxJS 和 数据驱动

RxJS 和 数据驱动

作者: JamesSawyer | 来源:发表于2017-08-12 15:43 被阅读146次

    数据驱动(data-driven) 是指将传递的数据和行为进行分离。这也是为什么RxJS能够以相同的范式来处理不同类型的数据源(比如数组,字符串,事件,AJAX请求等等)的核心原理。

    • 以数据作为中心,将数据从行为系统中分离出来,用数据去驱动业务
    • 没有数据,行为将不起作用,数据给行为带来升级,行为响应数据的变化,而不是等待数据的到来
    • 流(stream)只是一个传递过程,如果没有用户订阅,或者数据传递进来,流将保存闲置状态
    #1 stream如果没有被订阅将保持闲置状态.jpg

    数据生产者 producers

    数据的产生有不同的原因,这样造成数据源的来源有很多种情况。

    • 生产者有各种各样的形态和大小, Event Emitter 就是比较常见的一种生产者,它们用于响应鼠标点击或者网络请求,同时他们也是基于时间的数据源
    • 当处理不同类型的数据源,我们应当自然会想到使用不同类型的方式来处理。不如 event emitters 需要使用命名event handlers 来处理,Promises 需要一个连续传递的 thenable 函数来处理; setTimeout需要回调函数来处理; Arrays 需要通过循环来迭代数据

    但是Rx对不同类型的数据进行了包装处理,这样我们可以以相同的范式来处理不同类型的数据源,也就是说

    不同类型的数据源在事件驱动(或流驱动)的棱镜下观察都是一样的,
    就好比Rx.Observable 是一个锤子,把其余所有的数据类型当作钉子
    

    识别不同类型的数据源

    数据源广义的可以分为以下几类:

    • Emitted Data
    • Static Data
    • Generated Data

    1.Emitted Data

    发生数据是一种外部与系统交互产生的结果。可以来自与用户交互,比如点击鼠标,也可以是系统事件,比如读取文件。

    比如你请求数据,未来某个时间点,你接收到数据,对于这种情况, Promises 可能是一个好的解决方案。

    2.static data

    静态数据已经存在或者显示在系统(内存)中,比如 array ,string。人工的单元测试数据就划分到这一类型数据中。

    3.Generated data

    产生的数据是指间隔的或最终产生的数据,比如时钟每小时都会报时。

    比如无限产生的数据,不可能将其全部存储在内存中,值应当动态的被创建和产生给需要的使用者。

    数据类型的划分

    根据以下2个维度可以将数据划分为4类:

    • 值的多少: 单值(比如数字), 多值(比如数组)
    • 数据的处理方式: 同步的, 还是异步的
    数据类型的划分.jpg

    1.single-value && synchronous

    这是最简单的数据类型,比如数字,一个对象,我们可以通过 Rx.Observable.of 将其转换为一个 Obserable类型。

    但是一般处理简单类型的数据使用Observable,有点杀鸡用牛刀的味道,一般只有我们希望将简单类型的值和其它类型的流整合在一起时,才使用Obserable

    2.multi-value && synchronous

    我们可以将单值集合起来形成集合,主要是数组类型。

    我们可以使用 Rx.Obserable.from 将集合类型转换为Obserable类型

    3.single-value && asynchronous

    对于异步的情况,正是RxJS大放异彩的地方

    对于异步的情况,我们只能保证到吗在未来某个时间被处理,因此,后面的代码块不能依赖前面代码块的执行。

    对于单值异步的情况,使用 Promises 进行处理最好了,在RxJS中可以使用 Rx.Observable.fromPromise() 将promises转换为Observable类型。

    Rx.Observable.fromPromise($.ajax('/data'))
    

    4. multi-value && aynchronous

    这种类型的数据一般时间会作为数据来源的因子。比如DOM事件,不知道未来什么时候会产生。

    对这种数据的处理我们需要 混合迭代器和promise模式,通常的处理方式是使用 EventEmitter 进行处理。

    RxJS在javascript原有的EventEmitter的基础上对其进行了改进。可以使用 Rx.Observable.fromEvent() 将EventEmitter 转换为Observbale类型

    PUSH-BASED && PULL-BASE MODEL

    迭代器使用的 pull-based 模型, 而RXJS使用的是 push-based模型。

    #3数据推送和数据拉取模型.jpg
    • pull-based 对下面情况是非常拥有的: 当我们知道一个字能从计算后立即返回时。对于不知道值什么时候返回或者有没有值返回的情形,pull-based模型就失效了,比如鼠标点击,使用者是不知道下一次点击事件什么时候反生,或者发不发生
    • push-based模式中,生产者负责创建下一个数据,消费者只需要监听新的事件即可
    #3-1 push-based model.jpg

    Observable && Observer

    被观察者和观察者

    • 业务逻辑,比如值如何产生,怎么被发送归属于Observable,而所有的渲染细节,是否使用插件什么的处理逻辑归属于observer中的调度者
    • 要记住,无限事件发送,比如DO事件,将不会触发 complete() 方法,因此,取消订阅取决于使用者,可以采取手动取消订阅或者自动取消订阅机制
    #4被观察者和观察者.jpg

    Observable 基本api

    被观察者本质上一个函数

    下面用简单的方式来描述observable

    const observable = events => { // 时间队列
        const INTERVAL = 1 * 1000;
        let schedulerid;
    
        return { // 返回一个包含 'subscribe' 方法的对象
            subscribe: oberver => {  // 接收 observer 对象作为参数
                schedulerid = setInterval(() => {
                    if (events.length === 0) { // 如果没有时间处理了
                        observer.complete();
                        clearInterval(schedulerid);
                        schedulerid = undefined;
                    } else { // 如果有事件反生, 使用 observer.next()方法进行处理
                        observer.next(events.shift());
                    }
                }, INTERVAL);
    
                return {
                    unsubscribe: () => { // subscribe 方法返回一个unsubscribe 方法用于取消订阅
                        if (schedulerid) {
                            clearInterval(schedulerid);
                        }
                    }
                };
            }
        }
    }
    
    #4-1被观察者和观察者.jpg

    总结

    主要将了以下几个方面

    • RxJS采用了数据驱动的方式,数据和业务逻辑分离
    • RxJs对javascript的EventEmitter进行了改进,使其可以对事件进行推送
    • Push-based 和 Pull-based 方式的差异
    • 根据值的多少和处理方式2个维度,将数据源划分为4类
    • 简单Observable apis的介绍
      • Rx.Observable.of()
      • Rx.Observable.from()
      • Rx.Observable.fromPromise()
      • Rx.Observable.fromEvent()
    • Observable 和 Observer 之间的关系简单介绍

    相关文章

      网友评论

          本文标题:RxJS 和 数据驱动

          本文链接:https://www.haomeiwen.com/subject/adqjrxtx.html