基本定义
发布—订阅模式,定义了对象之间的一种一对多的依赖关系,即当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知。
订阅者把自己想订阅的事件注册到调度中心,当该事件触发时候,发布者发布该事件到调度中心(顺带上下文),由调度中心统一调度订阅者注册到调度中心的处理代码。
实现思路
- 初始化一个空对象作为事件调度中心
events = {},以 "事件" 为 key,事件发生后执行的方法为任务队列(数组)。 - 添加事件注册 on(event,callback)方法 , 判断如果事件调度中心(events)中存在该事件,直接将事件回调函数 push 至任务队列, 如果没有则以数组的形式增加该回调函数。
- 事件移除 off(event,callback) 方法, 找到该 "事件" event 的任务队列,如果数组存在 (
events[event]),如果 callback存在,查找 callback 的下标 index, 删除该回调函数;如果 callback 不存在, 删除该事件所以任务队列(events[event] = []). - 添加事件发布(触发) fire(event) 方法, 如果该 event 的任务队列存在,遍历数组(任务队列)中的 callback,并执行
- 单次触发事件:内部调用 fire 方法,执行之后删除此事件队列。
代码实现
class Event {
constructor () {
this.events = {}
}
// 注册事件
on (event, callback) {
if(!this.events[event]) this.events[event] = []
this.events[event].push(callback)
}
// 一次通知
once () {
let event = Array.prototype.shift.call(arguments)
this.fire(event, ...arguments)
delete this.events[event]
}
// 发布通知
fire () {
let event = Array.prototype.shift.call(arguments)
let callbacks = this.events[event]
if(!callbacks || !callbacks.length) return
callbacks.forEach(callback => {
callback.apply(this,arguments)
});
}
// 销毁监听
off (event, callback) {
let callbacks = this.events[event]
if (!callbacks) return false
if(!callback) return callbacks && (callbacks = [])
for(let i = callbacks.length-1; i>=0; i--){
let _cb = callbacks[i]
if ( _cb === callback) {
callbacks.splice(i,1)
}
}
}
}
// demo 测试
const event = new Event()
event.on("test",(index)=>{
console.log("test", index)
})
event.on("test",(index)=>{
console.log("test two", index)
})
event.fire("test",1)
event.fire("test",2)
event.once("test",3)
event.once("test",4)