JavaScript笔记之实现事件的发布订阅

最近根据工作需要重新梳理了旧的前端事件发布订阅机制,完善了订阅流程。具体代码如下:

1.创建 event 父级对象

因本人个人喜好,目前仍然使用 es5原型继承模式 设计类,并未直接使用 es6class。如有需要,简单适配下即可。

/*
* 事件对象
*/
let Event = function () {
  // 订阅事件列表
  // 通过对象存储事件的 key 与 value,方便进行存储与管理
  this._eventHandlerList = {}
}

2.注册事件

确保先注册再使用,避免脏事件污染,进行不必要的错误捕捉和处理。

Event.prototype.$register = function (event) {
  // 如果第一次注册,那么初始化监听器数组
  if (!this._eventHandlerList.hasOwnProperty(event)) {
    this._eventHandlerList[event] = []
  }
}

3.开启事件订阅监听

利用数组特性存储监听回调事件。

Event.prototype.$on = function (event, handler) {
  if (this._eventHandlerList.hasOwnProperty(event) && typeof handler === 'function') {
    this._eventHandlerList[event].push(handler)
  }
}

4.发布事件

触发事件时,遍历事件数组,进行循环调用触发。

Event.prototype.$emit = function (event, message) {
  if (this._eventHandlerList.hasOwnProperty(event)) {
    // 遍历执行回调
    for (let i in this._eventHandlerList[event]) {
      this._eventHandlerList[event][i](message)
    }
  }
}

5.移除事件订阅监听

移除事件时,与事件监听逻辑类似。遍历事件数组匹配事件,移除相应的订阅监听。

Event.prototype.$off = function (event, handler) {
  if (this._eventHandlerList.hasOwnProperty(event) && typeof handler === 'function') {
    // 移除缓存的监听函数
    // 固定写法,无需修改
    for (let i in this._eventHandlerList[event]) {
      if (this._eventHandlerList[event][i] === handler) {
        this._eventHandlerList[event].splice(i, i + 1)
        break
      }
    }
  }
}

6.注销事件

Event.prototype.$unregister = function (event) {
  // 如果已注册,那么销毁该属性
  if (!this._eventHandlerList.hasOwnProperty(event)) {
    delete this._eventHandlerList[event]
  }
}

7.具体使用

// 创建事件实例
let event = new Event()

// 注册 test 事件
event.$register('test')

// 监听 test 事件
event.$on('test', (msg) => {
  console.log(msg)	// 触发回调
})

// 触发 test 事件,触发值为 '测试测试123'
event.$emit('test', '测试测试123')

created by @SpiderWang
转载请注明作者及链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值