RxJS的另外四種實現(xiàn)方式(五)——使用生成器實現(xiàn)

接上一篇RxJS的另外四種實現(xiàn)方式(四)——性能最高的庫(續(xù))

js的生成器一般情況下使用場景很少肛真,開發(fā)者接觸的不是很多蚓让。不了解的可以先行查看js語法了解历极。

這里把其中的執(zhí)行順序圖解一下

調(diào)用方                                                                 數(shù)據(jù)源
next(value)--------------------------------------->              開始執(zhí)行生成器函數(shù)體
            <-------------------------------------------------yield value2
next(value3)--------------------------------------->
            <-------------------------------------------------yield value4
next(value5)--------------------------------------->
            <-------------------------------------------------return value6

以上是正常返回最后值的過程寞肖,也可以永遠不return新蟆,變成一個無限生成數(shù)據(jù)的過程。
另一種情況是提前終止

調(diào)用方                                                                 數(shù)據(jù)源
next(value)--------------------------------------->              開始執(zhí)行生成器函數(shù)體
            <-------------------------------------------------yield value2
next(value3)--------------------------------------->
            <-------------------------------------------------yield value4
return()--------------------------------------->

這種情況下相當(dāng)于主動關(guān)閉生成器帕翻。
可以向數(shù)據(jù)源的函數(shù)發(fā)出錯誤:

調(diào)用方                                                                 數(shù)據(jù)源
next(value)--------------------------------------->              開始執(zhí)行生成器函數(shù)體
            <-------------------------------------------------yield value2
next(value3)--------------------------------------->
            <-------------------------------------------------try catch
throw(err)

以上各種行為都可以對應(yīng)Rx,那么生成器和Rx的最大區(qū)別是什么呢?

就是誰是主動方揩晴,誰是被動方硫兰。在生成器中,調(diào)用方是主動方泳赋,相當(dāng)于主動pull數(shù)據(jù)腮郊,而Rx中衅鹿,數(shù)據(jù)源是主動方,相當(dāng)于主動push數(shù)據(jù)泵三。(這里和Rx中的推拉模式有區(qū)別)

那么如何使用生成器實現(xiàn)Rx呢烫幕?其實你估計已經(jīng)想到了,就是反過來即可:

Observable                                                    Observer
next(value)--------------------------------------->              開始執(zhí)行生成器函數(shù)體
            <-------------------------------------------------yield value2(得到返回值是value3)
next(value3)--------------------------------------->
            <-------------------------------------------------yield value4(返回值是value5)
next(value5)--------------------------------------->
            <-------------------------------------------------return value6()
done==true

于是我們就得到了由Observable主動推送過來的數(shù)據(jù)了。

我們還是以interval舉例

exports.interval = period => sink => {
    if (sink.next().done) return noop
    let i = 0;
    const id = setInterval(() => sink.next(i++).done && clearInterval(id), period)
    return () => clearInterval(id)
}

這里傳入的sink就是迭代器實例,我們主動調(diào)用next發(fā)送數(shù)據(jù)
這里我們判斷了next函數(shù)的返回值里面的done屬性,如果Observer主動取消訂閱了(在生成器函數(shù)里面執(zhí)行了return語句)那么done就為true

下面是filter操作符:

function* _filter(sink, f) {
    for (let done = sink.next().done; !done;) {
        let x = yield 0
        if (x === _done) break
        if (f(x)) done = sink.next(x).done
    }
    sink.next(_done)
    sink.return()
}
exports.filter = f => source => sink => source(_filter(sink, f))

_done是一個Symbol仅炊,用來表示Observable的complete事件
_filter是一個生成器蜕窿,調(diào)用它時傳入下一級的迭代器(Observer)
yeild 0 不斷獲取上一級的Observable的數(shù)據(jù)浙滤,一旦收到_done阴挣,立即跳出循環(huán),并將_done傳入sink中纺腊。

最后是實現(xiàn)Subscriber

function* subscribe(n, e, c) {
    while (true) {
        try {
            let result = yield 0
            while (result !== _done) {
                if (n(result) === _done) return
                result = yield 0
            }
            c && c()
        } catch (err) {
            e && e(err)
        }
    }
}
exports.subscribe = subscribe

是一個死循環(huán)畔咧,直到收到_done茎芭,或者拋出異常。
至此誓沸,我們的Rx的基本功能已經(jīng)實現(xiàn)梅桩,由于生成器的性能較差,所以本人沒有花很多時間去完善各種操作符拜隧,只作為一種可以實現(xiàn)的方式展示出來宿百。

下一篇我們介紹最后一種實現(xiàn)方法。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末洪添,一起剝皮案震驚了整個濱河市垦页,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌干奢,老刑警劉巖外臂,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異律胀,居然都是意外死亡宋光,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進店門炭菌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來罪佳,“玉大人,你說我怎么就攤上這事黑低∽秆蓿” “怎么了?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵克握,是天一觀的道長蕾管。 經(jīng)常有香客問我,道長菩暗,這世上最難降的妖魔是什么掰曾? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮停团,結(jié)果婚禮上旷坦,老公的妹妹穿的比我還像新娘。我一直安慰自己佑稠,他們只是感情好秒梅,可當(dāng)我...
    茶點故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著舌胶,像睡著了一般捆蜀。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天辆它,我揣著相機與錄音誊薄,去河邊找鬼。 笑死娩井,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的似袁。 我是一名探鬼主播洞辣,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼昙衅!你這毒婦竟也來了扬霜?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤而涉,失蹤者是張志新(化名)和其女友劉穎著瓶,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啼县,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡材原,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了季眷。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片余蟹。...
    茶點故事閱讀 39,932評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖子刮,靈堂內(nèi)的尸體忽然破棺而出威酒,到底是詐尸還是另有隱情,我是刑警寧澤挺峡,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布葵孤,位于F島的核電站,受9級特大地震影響橱赠,放射性物質(zhì)發(fā)生泄漏尤仍。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一狭姨、第九天 我趴在偏房一處隱蔽的房頂上張望吓著。 院中可真熱鬧,春花似錦送挑、人聲如沸绑莺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纺裁。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間欺缘,已是汗流浹背栋豫。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留谚殊,地道東北人丧鸯。 一個月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像嫩絮,于是被迫代替她去往敵國和親丛肢。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,884評論 2 354

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理剿干,服務(wù)發(fā)現(xiàn)蜂怎,斷路器,智...
    卡卡羅2017閱讀 134,656評論 18 139
  • 1 場景問題# 1.1 繼續(xù)導(dǎo)出數(shù)據(jù)的應(yīng)用框架## 在討論工廠方法模式的時候置尔,提到了一個導(dǎo)出數(shù)據(jù)的應(yīng)用框架杠步。 對于...
    七寸知架構(gòu)閱讀 5,739評論 1 64
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,129評論 25 707
  • 引入依賴: implementation 'io.reactivex.rxjava2:rxandroid:2.0....
    為夢想戰(zhàn)斗閱讀 1,303評論 0 0
  • “協(xié)程(coroutine)”于我而言還是比較新的概念,Lua 也是剛接觸不久榜轿。不過碰巧這段時間我又在看 ES6 ...
    NARUTO_86閱讀 1,713評論 0 3