RxJS 和 数据驱动

数据驱动(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 之间的关系简单介绍
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,884评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,212评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,351评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,412评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,438评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,127评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,714评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,636评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,173评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,264评论 3 339
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,402评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,073评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,763评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,253评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,382评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,749评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,403评论 2 358

推荐阅读更多精彩内容

  • 一.背景介绍 Rx(Reactive Extension -- 响应式扩展 http://reactivex.io...
    爱上Shu的小刺猬阅读 2,046评论 1 3
  • 介绍 RxJS是一个异步编程的库,同时它通过observable序列来实现基于事件的编程。它提供了一个核心的类型:...
    泓荥阅读 16,610评论 0 12
  • 本文章内部分图片资源来自RayWenderlich.com 本文结合自己的理解来总结介绍一下RxSwift最基本的...
    FKSky阅读 2,887评论 4 14
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,685评论 18 139
  • 关于Rxjs的现状 鉴于响应式编程近几年才开始真正流行,而且响应式的理念也并不是在所有领域都深得人心,对于不是特别...
    吧啦啦小汤圆阅读 2,922评论 0 7