接上篇 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