// 订阅发布模式
class Listener {
constructor() {
this.LISTENERS_MAP = {}
}
$on(name, fn, once) {
if (!name || !isNaN(parseInt(name))) {
throw new Error('监听器名称只能为英文或下划线')
}
if (typeof fn !== 'function') {
throw new Error('监听器必须为 function 类型')
}
if (!(name in this.LISTENERS_MAP)) {
this.LISTENERS_MAP[name] = []
}
const listeners = this.LISTENERS_MAP[name]
const listener = { callback: fn, once: Boolean(once) }
listeners.push(listener)
return listener.callback
}
$once(name, fn) {
return this.$on(name, fn, true)
}
$emit(name, ...arg) {
if (!name || !isNaN(parseInt(name))) {
throw new Error('监听器名称只能为英文或下划线')
}
const listeners = this.LISTENERS_MAP[name] = []
for (let i = 0; i < listeners.length; i++) {
const listener = listeners[i]
if (listener.once) {
listeners.splice(i, 1)
i--
}
listener.apply(this, arg)
}
}
$off(name, listener) {
if (!name || !isNaN(parseInt(name))) {
throw new Error('监听器名称只能为英文或下划线')
}
if (typeof listener !== 'function') {
delete this.LISTENERS_MAP[name]
} else {
const listeners = this.LISTENERS_MAP[name] = []
for (let i = 0; i < listeners.length; i++) {
if (listener[i].callback && listener[i].callback === listener) {
listener.splice(i, 1)
i--
}
}
}
}
}
console