接上篇 RxJS的另外四種實現方式(一)——代碼最小的庫html
上篇咱們展現了生產者interval和操做符filter的實現,接下來咱們看一下消費者subscriber的實現閉包
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;
exports.subscribe = (n, e, c) => source => source(n, err => err ? e && e(err) : c && c())
咱們能夠看到,若是讓讀者自行擴展其餘操做符或者生產者都是十分容易的。相反若是要寫出正確的callbag的話,就十分考驗技術了。函數
你們能夠自行驗證兩個庫的運行狀況是否正確:性能
//pipe語法 interval(1000) |> filter(x => x > 4) |> subscribe(console.log) //使用pipe函數代替 pipe(interval(1000),filter(x => x > 4) ,subscribe(console.log))
最後再展現一個skip操做符的實現源碼ui
exports.skip = count => source => (n, c) => { let _count = count; let _n = () => (--_count === 0 && (_n = n)); return source(d => _n(d), c) }
與callbag類似,最小庫使用高階函數來代替傳統的observable、observer等對象,因此不須要核心庫(基類)。傳統方式在建立observable的時候傳入observer對象,做爲代替方案,是向observable高階函數傳入next和complete回調函數做爲訂閱行爲。next和complete回調函數合起來能夠當作是observer對象。而observer分紅了next和complete回調函數的好處是,能夠進行分開傳遞,有時候就能夠直接透傳,如上文的skip函數中的complete回調函數c,直接透傳到源observable裏面。訂閱行爲即調用observable函數返回值被利用來做爲dispose行爲,不少時候就會隱含的進行傳遞如上面的skip操做符。js的許多語法可使得代碼更加短小精悍,例如:code
固然這個庫最核心的就是函數閉包,本質上來講,定義函數就至關於定義了一個類,閉包裏面的變量都是這個函數調用後的僞對象的屬性,這致使了,雖然代碼已經極端短小,但性能卻不是最高的緣由。下一篇我將介紹最高性能的庫的實現方法。server
(未完待續)htm