JavaScript 设计模式-发布订阅模式
发布订阅模式
on
: 负责订阅事件,emit
负责发布事件,eventMap
: 事件名称和事件的映射
class EventEmitter {
constructor() {
// eventMap 用来存储事件和监听函数之间的关系
this.eventMap = {}
}
/**
* # >>>>>>> 注册事件 / 订阅事件
* type: 这里就代表事件的名称
* handler: 代表事件, 必须是一个函数
*/
on(type, handler) {
if (!(handler instanceof Function)) {
throw new Error('Must be a Function!')
}
// 判断 type 事件对应的队列是否存在
if (!this.eventMap[type]) {
// 新建
this.eventMap[type] = []
}
// 将 handler 推入 队列
this.eventMap[type].push(handler)
}
/**
* # >>>>>>> 发布事件
* type: 发布事件的名称
* params: 携带的参数
*/
emit(type, params) {
// 事件是被订阅的: 对应的事件队列存在
if (this.eventMap[type]) {
this.eventMap[type].forEach((handler, index) => {
// 传递params
handler(params)
})
}
}
/**
* # 要卸载的 事件名称 对应的函数: event.off('event-name-a',handleA), 把 event-name-a 对应的 handleA 卸载,其他事件保留
* type: 事件的名称
* handler: 代表事件, 必须是一个函数
*/
off(type, handler) {
if (this.eventMap[type]) {
this.eventMap[type].splice(this.eventMap[type].indexOf(handler) >>> 0, 1)
}
}
}
const myEvent = new EventEmitter()
const testHandler = function (params) {
console.log(`test事件被触发了,testHandler 接收到的入参是${params}`)
}
// 监听 test 事件
myEvent.on('test', testHandler)
myEvent.on('testb', testHandler)
// 在触发 test 事件的同时,传入希望 testHandler 感知的参数
myEvent.emit('test', 'newSate aaa')
myEvent.emit('testb', 'newSate bbb')
console.info(myEvent)
Keep learning