原文參考: https://www.cxymsg.com/guide/jsWritten.html#%E5%AE%9E%E7%8E%B0event-event-bus
class EventEmitter {
constructor() {
this._event = this._event || new Map() // 儲(chǔ)存事件
this._maxListeners = this._maxListeners || 10 // 設(shè)置監(jiān)聽(tīng)上限
}
}
EventEmitter.prototype.emit = function (type, ...args) {
let handler = null
handler = this._event.get(type)
if (Array.isArray(handler)) {
// 有多個(gè)監(jiān)聽(tīng)者,需要依次觸發(fā)
for (let i = 0; i < handler.length; i++) {
if (args.length > 0) {
handler[i].apply(this, args)
} else {
handler[i].call(this)
}
}
} else if (handler && typeof handler === 'function') {
if (args.length > 0) {
handler.apply(this, args)
} else {
handler.call(this)
}
}
return true
}
EventEmitter.prototype.addListener = function (type, fn) {
let handler = this._event.get(type)
if (!handler) {
this._event.set(type, fn)
} else if (handler && typeof handler === 'function') {
// 如果handler是函數(shù),說(shuō)明目前已經(jīng)存在一個(gè)監(jiān)聽(tīng)者
this._event.set(type, [handler, fn])
} else {
// 已經(jīng)有多個(gè)監(jiān)聽(tīng)者,直接push
handler.push(fn)
}
}
EventEmitter.prototype.removeListener = function (type, fn) {
let handler = this._event.get(type)
if (handler && typeof handler === 'function') {
// 只有一個(gè)監(jiān)聽(tīng)者,直接刪除
this._event.delete(type, fn)
} else if (Array.isArray(handler)) {
// 是數(shù)組,說(shuō)明被監(jiān)聽(tīng)多次,要找到對(duì)應(yīng)的函數(shù)
let position = -1
for(let i = 0; i < handler.length; i++) {
if (handler[i] === fn) {
position = i
}
}
// 如果匹配,從數(shù)組中移除
if (position !== -1) {
handler.splice(position, 1)
// 移除后,如果監(jiān)聽(tīng)只剩一個(gè),那么取消數(shù)組,以函數(shù)形式保存
if (handler.length === 1) {
this._event.set(type, handler[0])
}
} else {
return this
}
}
}