上篇我們展示了生產(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ù))