手写发布订阅器

发布订阅器的基本实现其实非常简单,核心思路就是维护一个对象,对象的key、value分别表示事件及其对应的回调函数数组。然后可以通过暴露的方法去清除事件对应的回调,也可以通过方法去触发事件对应的回调。

属性:消息队列

{
  "click": [fn1, fn2, fn3],
  "abc": [fnA, fnB]
}

/*
能向消息队列里添加内容 on
删除消息队列中的内容   off
触发消息队列内的内容   emit
*/
class Observer {
  constructor(){
    this.message = {}
  }

  // 添加事件与回调
  on(type, fn){
    if(!this.message[type]){
      this.message[type] = [];  // 效果同:this.message[type] = this.message[type] || [];
    }
    this.message[type].push(fn)
  }

  // 移除事件对应的回调
  off(type, fn){
    if(!this.message[type]) return;
    if(!fn) {
      delete(this.message[type]); // this.message[type] = undefined;
      return;
    }
    this.message[type] = this.message[type].filter(fun => fun !== fn )
  }

  // 添加只允许被执行一次的事件
  once(type, fn){
    let onceFn = () => {
      fn();
      this.off(type);
    }
    this.on(type, onceFn);
  }

  // 触发事件对应回调
  emit(type){
    if(!this.message[type]) return;
    this.message[type].forEach(item => item());
  }

}

// -------------------------  测试 -------------------------

function funSing(){
  console.log('他会唱歌!');
}
function funDance(){
  console.log('他还会跳舞!');
}
function funRap(){
  console.log('他还会Rap??');
}
function funBasketball(){
  console.log('嗯?他还会打篮球??');
}

let person1 = new Observer();

// 向person1委托一些内容,帮我观察
person1.on('singAndDance', funSing);
person1.on('singAndDance', funDance);

person1.once('Rap', funRap);

person1.off('singAndDance', funSing);

person1.emit('singAndDance');
person1.emit('singAndDance');
person1.emit('Rap');
person1.emit('Rap');

console.log( person1 );

完美运行 !

注意!触发完一次 Rap 对应的事件,message 中就不再存在 Rap 事件了,是因为我们在 once 中设定,执行完绑定的函数后,通过 off 删除对应的事件。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

麦田里的POLO桔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值