RxJS的另外四種實(shí)現(xiàn)方式(二)——代碼最小的庫(kù)(續(xù))

接上篇 RxJS的另外四種實(shí)現(xiàn)方式(一)——代碼最小的庫(kù)

上篇我們展示了生產(chǎn)者interval和操作符filter的實(shí)現(xiàn),接下來我們看一下消費(fèi)者subscriber的實(shí)現(xiàn)

callbag的實(shí)現(xiàn)

const subscribe = (listener = {}) => source => {
  if (typeof listener === "function") {
    listener = { next: listener };
  }

  let { next, error, complete } = listener;
  let talkback;

  source(0, (t, d) => {
    if (t === 0) {
      talkback = d;
    }
    if (t === 1 && next) next(d);
    if (t === 1 || t === 0) talkback(1);  // Pull
    if (t === 2 && !d && complete) complete();
    if (t === 2 && !!d && error) error( d );
  });

  const dispose = () => {
    if (talkback) talkback(2);
  }

  return dispose;
}

module.exports = subscribe;

最小庫(kù)的實(shí)現(xiàn)

exports.subscribe = (n, e, c) => source => source(n, err => err ? e && e(err) : c && c())

我們可以看到,如果讓讀者自行擴(kuò)展其他操作符或者生產(chǎn)者都是十分容易的。相反如果要寫出正確的callbag的話,就十分考驗(yàn)技術(shù)了。

大家可以自行驗(yàn)證兩個(gè)庫(kù)的運(yùn)行情況是否正確:

//pipe語(yǔ)法
interval(1000) |> filter(x => x > 4) |> subscribe(console.log)
//使用pipe函數(shù)代替
pipe(interval(1000),filter(x => x > 4) ,subscribe(console.log))

最后再展示一個(gè)skip操作符的實(shí)現(xiàn)源碼

exports.skip = count => source => (n, c) => {
    let _count = count;
    let _n = () => (--_count === 0 && (_n = n));
    return source(d => _n(d), c)
}

最小庫(kù)實(shí)現(xiàn)技術(shù)手段

與callbag相似,最小庫(kù)使用高階函數(shù)來代替?zhèn)鹘y(tǒng)的observable、observer等對(duì)象,所以不需要核心庫(kù)(基類)。傳統(tǒng)方式在創(chuàng)建observable的時(shí)候傳入observer對(duì)象,作為代替方案,是向observable高階函數(shù)傳入next和complete回調(diào)函數(shù)作為訂閱行為。next和complete回調(diào)函數(shù)合起來可以看成是observer對(duì)象。而observer分成了next和complete回調(diào)函數(shù)的好處是,可以進(jìn)行分開傳遞,有時(shí)候就可以直接透?jìng)鳎缟衔牡膕kip函數(shù)中的complete回調(diào)函數(shù)c,直接透?jìng)鞯皆磑bservable里面。訂閱行為即調(diào)用observable函數(shù)返回值被利用來作為dispose行為,很多時(shí)候就會(huì)隱含的進(jìn)行傳遞如上面的skip操作符。js的許多語(yǔ)法可以使得代碼更加短小精悍,例如:

  • 箭頭函數(shù)為表達(dá)式的時(shí)候,無需寫大括號(hào),以及return
  • js的逗號(hào)表達(dá)式,可以返回表達(dá)式最后一個(gè)逗號(hào)后面的值
  • js的邏輯運(yùn)算符&&、||可以用來代替if語(yǔ)句等
  • js的函數(shù)變量可以替換成新的函數(shù),使得行為發(fā)生變化

當(dāng)然這個(gè)庫(kù)最核心的就是函數(shù)閉包,本質(zhì)上來說,定義函數(shù)就相當(dāng)于定義了一個(gè)類,閉包里面的變量都是這個(gè)函數(shù)調(diào)用后的偽對(duì)象的屬性,這導(dǎo)致了,雖然代碼已經(jīng)極端短小,但性能卻不是最高的原因。下一篇我將介紹最高性能的庫(kù)的實(shí)現(xiàn)方法。

(未完待續(xù))

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 介紹 RxJS是一個(gè)異步編程的庫(kù),同時(shí)它通過observable序列來實(shí)現(xiàn)基于事件的編程。它提供了一個(gè)核心的類型:...
    泓滎閱讀 16,767評(píng)論 0 12
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,872評(píng)論 25 709
  • 接上篇RxJS的另外四種實(shí)現(xiàn)方式(序) 起因 想到這個(gè)庫(kù)的原因,是看了callbag庫(kù)想到的,callbag庫(kù)的原...
    一個(gè)灰閱讀 606評(píng)論 0 1
  • 【日有所得】 一、序言 1.你的初心是什么?你為什么來?曹老師為什么來? 緣是什么? 認(rèn)真、開放、坦誠(chéng)、信心、“合...
    梅苑聽雪73閱讀 1,125評(píng)論 0 0
  • 整個(gè)十月 半月紅,半月黃 我掛在樹枝上驚嘆 我是紅葉 是我的垂暮染紅了夕陽(yáng) 我臨終的妝扮,只為來世更好的遇見 與你...
    流沙l閱讀 525評(píng)論 2 4

友情鏈接更多精彩內(nèi)容