RxJS的另外四种实现方式(二)——代码最小的库(续)

接上篇 RxJS的另外四种实现方式(一)——代码最小的库

上篇我们展示了生产者interval和操作符filter的实现,接下来我们看一下消费者subscriber的实现

callbag的实现

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操作符的实现源码

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的许多语法可以使得代码更加短小精悍,例如:

  • 箭头函数为表达式的时候,无需写大括号,以及return
  • js的逗号表达式,可以返回表达式最后一个逗号后面的值
  • js的逻辑运算符&&、||可以用来代替if语句等
  • js的函数变量可以替换成新的函数,使得行为发生变化

当然这个库最核心的就是函数闭包,本质上来说,定义函数就相当于定义了一个类,闭包里面的变量都是这个函数调用后的伪对象的属性,这导致了,虽然代码已经极端短小,但性能却不是最高的原因。下一篇我将介绍最高性能的库的实现方法。

(未完待续)

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 介绍 RxJS是一个异步编程的库,同时它通过observable序列来实现基于事件的编程。它提供了一个核心的类型:...
    泓荥阅读 16,759评论 0 12
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 177,482评论 25 709
  • 接上篇RxJS的另外四种实现方式(序) 起因 想到这个库的原因,是看了callbag库想到的,callbag库的原...
    一个灰阅读 595评论 0 1
  • 【日有所得】 一、序言 1.你的初心是什么?你为什么来?曹老师为什么来? 缘是什么? 认真、开放、坦诚、信心、“合...
    梅苑听雪73阅读 1,121评论 0 0
  • 整个十月 半月红,半月黄 我挂在树枝上惊叹 我是红叶 是我的垂暮染红了夕阳 我临终的妆扮,只为来世更好的遇见 与你...
    流沙l阅读 523评论 2 4

友情链接更多精彩内容