RxJS 和 數(shù)據(jù)驅(qū)動(dòng)

數(shù)據(jù)驅(qū)動(dòng)(data-driven) 是指將傳遞的數(shù)據(jù)和行為進(jìn)行分離晓折。這也是為什么RxJS能夠以相同的范式來(lái)處理不同類型的數(shù)據(jù)源(比如數(shù)組,字符串鳖目,事件狸眼,AJAX請(qǐng)求等等)的核心原理。

  • 以數(shù)據(jù)作為中心谢鹊,將數(shù)據(jù)從行為系統(tǒng)中分離出來(lái)算吩,用數(shù)據(jù)去驅(qū)動(dòng)業(yè)務(wù)
  • 沒有數(shù)據(jù),行為將不起作用佃扼,數(shù)據(jù)給行為帶來(lái)升級(jí)偎巢,行為響應(yīng)數(shù)據(jù)的變化,而不是等待數(shù)據(jù)的到來(lái)
  • 流(stream)只是一個(gè)傳遞過(guò)程松嘶,如果沒有用戶訂閱,或者數(shù)據(jù)傳遞進(jìn)來(lái)挎扰,流將保存閑置狀態(tài)
#1 stream如果沒有被訂閱將保持閑置狀態(tài).jpg

數(shù)據(jù)生產(chǎn)者 producers

數(shù)據(jù)的產(chǎn)生有不同的原因翠订,這樣造成數(shù)據(jù)源的來(lái)源有很多種情況。

  • 生產(chǎn)者有各種各樣的形態(tài)和大小遵倦, Event Emitter 就是比較常見的一種生產(chǎn)者尽超,它們用于響應(yīng)鼠標(biāo)點(diǎn)擊或者網(wǎng)絡(luò)請(qǐng)求,同時(shí)他們也是基于時(shí)間的數(shù)據(jù)源
  • 當(dāng)處理不同類型的數(shù)據(jù)源梧躺,我們應(yīng)當(dāng)自然會(huì)想到使用不同類型的方式來(lái)處理似谁。不如 event emitters 需要使用命名event handlers 來(lái)處理,Promises 需要一個(gè)連續(xù)傳遞的 thenable 函數(shù)來(lái)處理掠哥; setTimeout需要回調(diào)函數(shù)來(lái)處理巩踏; Arrays 需要通過(guò)循環(huán)來(lái)迭代數(shù)據(jù)

但是Rx對(duì)不同類型的數(shù)據(jù)進(jìn)行了包裝處理,這樣我們可以以相同的范式來(lái)處理不同類型的數(shù)據(jù)源续搀,也就是說(shuō)

不同類型的數(shù)據(jù)源在事件驅(qū)動(dòng)(或流驅(qū)動(dòng))的棱鏡下觀察都是一樣的塞琼,
就好比Rx.Observable 是一個(gè)錘子,把其余所有的數(shù)據(jù)類型當(dāng)作釘子

識(shí)別不同類型的數(shù)據(jù)源

數(shù)據(jù)源廣義的可以分為以下幾類:

  • Emitted Data
  • Static Data
  • Generated Data

1.Emitted Data

發(fā)生數(shù)據(jù)是一種外部與系統(tǒng)交互產(chǎn)生的結(jié)果禁舷”肷迹可以來(lái)自與用戶交互毅往,比如點(diǎn)擊鼠標(biāo),也可以是系統(tǒng)事件派近,比如讀取文件攀唯。

比如你請(qǐng)求數(shù)據(jù),未來(lái)某個(gè)時(shí)間點(diǎn)渴丸,你接收到數(shù)據(jù)侯嘀,對(duì)于這種情況, Promises 可能是一個(gè)好的解決方案曙强。

2.static data

靜態(tài)數(shù)據(jù)已經(jīng)存在或者顯示在系統(tǒng)(內(nèi)存)中残拐,比如 array ,string。人工的單元測(cè)試數(shù)據(jù)就劃分到這一類型數(shù)據(jù)中碟嘴。

3.Generated data

產(chǎn)生的數(shù)據(jù)是指間隔的或最終產(chǎn)生的數(shù)據(jù)溪食,比如時(shí)鐘每小時(shí)都會(huì)報(bào)時(shí)。

比如無(wú)限產(chǎn)生的數(shù)據(jù)娜扇,不可能將其全部存儲(chǔ)在內(nèi)存中错沃,值應(yīng)當(dāng)動(dòng)態(tài)的被創(chuàng)建和產(chǎn)生給需要的使用者。

數(shù)據(jù)類型的劃分

根據(jù)以下2個(gè)維度可以將數(shù)據(jù)劃分為4類:

  • 值的多少: 單值(比如數(shù)字)雀瓢, 多值(比如數(shù)組)
  • 數(shù)據(jù)的處理方式: 同步的枢析, 還是異步的
數(shù)據(jù)類型的劃分.jpg

1.single-value && synchronous

這是最簡(jiǎn)單的數(shù)據(jù)類型,比如數(shù)字刃麸,一個(gè)對(duì)象醒叁,我們可以通過(guò) Rx.Observable.of 將其轉(zhuǎn)換為一個(gè) Obserable類型。

但是一般處理簡(jiǎn)單類型的數(shù)據(jù)使用Observable,有點(diǎn)殺雞用牛刀的味道泊业,一般只有我們希望將簡(jiǎn)單類型的值和其它類型的流整合在一起時(shí)把沼,才使用Obserable

2.multi-value && synchronous

我們可以將單值集合起來(lái)形成集合,主要是數(shù)組類型吁伺。

我們可以使用 Rx.Obserable.from 將集合類型轉(zhuǎn)換為Obserable類型

3.single-value && asynchronous

對(duì)于異步的情況肯尺,正是RxJS大放異彩的地方靠抑。

對(duì)于異步的情況由捎,我們只能保證到嗎在未來(lái)某個(gè)時(shí)間被處理穆趴,因此,后面的代碼塊不能依賴前面代碼塊的執(zhí)行窟却。

對(duì)于單值異步的情況昼丑,使用 Promises 進(jìn)行處理最好了,在RxJS中可以使用 Rx.Observable.fromPromise() 將promises轉(zhuǎn)換為Observable類型夸赫。

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

4. multi-value && aynchronous

這種類型的數(shù)據(jù)一般時(shí)間會(huì)作為數(shù)據(jù)來(lái)源的因子矾克。比如DOM事件,不知道未來(lái)什么時(shí)候會(huì)產(chǎn)生。

對(duì)這種數(shù)據(jù)的處理我們需要 混合迭代器和promise模式胁附,通常的處理方式是使用 EventEmitter 進(jìn)行處理酒繁。

RxJS在javascript原有的EventEmitter的基礎(chǔ)上對(duì)其進(jìn)行了改進(jìn)】仄蓿可以使用 Rx.Observable.fromEvent() 將EventEmitter 轉(zhuǎn)換為Observbale類型

PUSH-BASED && PULL-BASE MODEL

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

#3數(shù)據(jù)推送和數(shù)據(jù)拉取模型.jpg
  • pull-based 對(duì)下面情況是非常擁有的: 當(dāng)我們知道一個(gè)字能從計(jì)算后立即返回時(shí)弓候。對(duì)于不知道值什么時(shí)候返回或者有沒有值返回的情形郎哭,pull-based模型就失效了,比如鼠標(biāo)點(diǎn)擊菇存,使用者是不知道下一次點(diǎn)擊事件什么時(shí)候反生夸研,或者發(fā)不發(fā)生
  • push-based模式中,生產(chǎn)者負(fù)責(zé)創(chuàng)建下一個(gè)數(shù)據(jù)依鸥,消費(fèi)者只需要監(jiān)聽新的事件即可
#3-1 push-based model.jpg

Observable && Observer

被觀察者和觀察者

  • 業(yè)務(wù)邏輯亥至,比如值如何產(chǎn)生,怎么被發(fā)送歸屬于Observable,而所有的渲染細(xì)節(jié)贱迟,是否使用插件什么的處理邏輯歸屬于observer中的調(diào)度者
  • 要記住姐扮,無(wú)限事件發(fā)送,比如DO事件衣吠,將不會(huì)觸發(fā) complete() 方法茶敏,因此,取消訂閱取決于使用者缚俏,可以采取手動(dòng)取消訂閱或者自動(dòng)取消訂閱機(jī)制
#4被觀察者和觀察者.jpg

Observable 基本api

被觀察者本質(zhì)上一個(gè)函數(shù)

下面用簡(jiǎn)單的方式來(lái)描述observable

const observable = events => { // 時(shí)間隊(duì)列
    const INTERVAL = 1 * 1000;
    let schedulerid;

    return { // 返回一個(gè)包含 'subscribe' 方法的對(duì)象
        subscribe: oberver => {  // 接收 observer 對(duì)象作為參數(shù)
            schedulerid = setInterval(() => {
                if (events.length === 0) { // 如果沒有時(shí)間處理了
                    observer.complete();
                    clearInterval(schedulerid);
                    schedulerid = undefined;
                } else { // 如果有事件反生惊搏, 使用 observer.next()方法進(jìn)行處理
                    observer.next(events.shift());
                }
            }, INTERVAL);

            return {
                unsubscribe: () => { // subscribe 方法返回一個(gè)unsubscribe 方法用于取消訂閱
                    if (schedulerid) {
                        clearInterval(schedulerid);
                    }
                }
            };
        }
    }
}
#4-1被觀察者和觀察者.jpg

總結(jié)

主要將了以下幾個(gè)方面

  • RxJS采用了數(shù)據(jù)驅(qū)動(dòng)的方式,數(shù)據(jù)和業(yè)務(wù)邏輯分離
  • RxJs對(duì)javascript的EventEmitter進(jìn)行了改進(jìn)忧换,使其可以對(duì)事件進(jìn)行推送
  • Push-based 和 Pull-based 方式的差異
  • 根據(jù)值的多少和處理方式2個(gè)維度恬惯,將數(shù)據(jù)源劃分為4類
  • 簡(jiǎn)單Observable apis的介紹
    • Rx.Observable.of()
    • Rx.Observable.from()
    • Rx.Observable.fromPromise()
    • Rx.Observable.fromEvent()
  • Observable 和 Observer 之間的關(guān)系簡(jiǎn)單介紹
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市包雀,隨后出現(xiàn)的幾起案子宿崭,更是在濱河造成了極大的恐慌亲铡,老刑警劉巖才写,帶你破解...
    沈念sama閱讀 212,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異奖蔓,居然都是意外死亡赞草,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門吆鹤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)厨疙,“玉大人,你說(shuō)我怎么就攤上這事疑务≌雌啵” “怎么了梗醇?”我有些...
    開封第一講書人閱讀 158,369評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)撒蟀。 經(jīng)常有香客問(wèn)我叙谨,道長(zhǎng),這世上最難降的妖魔是什么保屯? 我笑而不...
    開封第一講書人閱讀 56,799評(píng)論 1 285
  • 正文 為了忘掉前任手负,我火速辦了婚禮,結(jié)果婚禮上姑尺,老公的妹妹穿的比我還像新娘竟终。我一直安慰自己,他們只是感情好切蟋,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評(píng)論 6 386
  • 文/花漫 我一把揭開白布统捶。 她就那樣靜靜地躺著,像睡著了一般敦姻。 火紅的嫁衣襯著肌膚如雪瘾境。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,096評(píng)論 1 291
  • 那天镰惦,我揣著相機(jī)與錄音迷守,去河邊找鬼。 笑死旺入,一個(gè)胖子當(dāng)著我的面吹牛兑凿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播茵瘾,決...
    沈念sama閱讀 39,159評(píng)論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼礼华,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了拗秘?” 一聲冷哼從身側(cè)響起圣絮,我...
    開封第一講書人閱讀 37,917評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎雕旨,沒想到半個(gè)月后扮匠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,360評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡凡涩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評(píng)論 2 327
  • 正文 我和宋清朗相戀三年棒搜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片活箕。...
    茶點(diǎn)故事閱讀 38,814評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡力麸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情克蚂,我是刑警寧澤闺鲸,帶...
    沈念sama閱讀 34,509評(píng)論 4 334
  • 正文 年R本政府宣布,位于F島的核電站埃叭,受9級(jí)特大地震影響翠拣,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜游盲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評(píng)論 3 317
  • 文/蒙蒙 一误墓、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧益缎,春花似錦谜慌、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至令哟,卻和暖如春恼琼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背屏富。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工晴竞, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人狠半。 一個(gè)月前我還...
    沈念sama閱讀 46,641評(píng)論 2 362
  • 正文 我出身青樓噩死,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親神年。 傳聞我的和親對(duì)象是個(gè)殘疾皇子已维,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容

  • 一.背景介紹 Rx(Reactive Extension -- 響應(yīng)式擴(kuò)展 http://reactivex.io...
    愛上Shu的小刺猬閱讀 2,039評(píng)論 1 3
  • 介紹 RxJS是一個(gè)異步編程的庫(kù),同時(shí)它通過(guò)observable序列來(lái)實(shí)現(xiàn)基于事件的編程已日。它提供了一個(gè)核心的類型:...
    泓滎閱讀 16,590評(píng)論 0 12
  • 本文章內(nèi)部分圖片資源來(lái)自RayWenderlich.com 本文結(jié)合自己的理解來(lái)總結(jié)介紹一下RxSwift最基本的...
    FKSky閱讀 2,869評(píng)論 4 14
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理垛耳,服務(wù)發(fā)現(xiàn),斷路器飘千,智...
    卡卡羅2017閱讀 134,638評(píng)論 18 139
  • 關(guān)于Rxjs的現(xiàn)狀 鑒于響應(yīng)式編程近幾年才開始真正流行堂鲜,而且響應(yīng)式的理念也并不是在所有領(lǐng)域都深得人心,對(duì)于不是特別...
    吧啦啦小湯圓閱讀 2,913評(píng)論 0 7