实现以下功能:
1. on 多次绑定,即可以多次执行,直到被off掉
2. once 一次绑定,即只能执行一次便自动off掉,或未执行也可以被off掉
3. emit 触发事件,且能够传入参数
4. off 取消事件
分析:
1. on和once注册函数,并存储起来,按照注册顺序依次执行
2. emit时找到对应的函数并执行
3. off找到对应的函数,并从对象中删除
class EventBus {
// 初始化
constructor(){
this.bus = {}
}
on(type, fn, isOnce = false) {
const bus = this.bus
if(bus[type] == null) bus[type] = [] // 如果该类型不存在,则定义
bus[type].push({ fn, isOnce }) // 将该事件注册到该类型中
}
once(type,fn) {
// 做法类似与on,所以直接调用即可,isOnce是用来区分的
this.on(type,fn,true)
}
off(type, fn) {
const fnList = this.bus[type] // 拿到该类型下的所有事件
if (fnList == null || !fnList.length) return; // 当该类型没有事件或没有该类型时直接返回
if(!fn) {
// 没有传入fn,则off掉该类型的所有注册事件
this.bus[type] = []
} else {
this.bus[type] = this.bus[type].filter(item => item.fn !== fn)
}
}
emit(type,...arg){
const fnList = this.bus[type] // 拿到该类型下的所有事件
if (fnList == null || !fnList.length) return; // 当该类型没有事件或没有该类型时直接返回
this.bus[type] = fnList.filter(item => {
// 执行事件
const {fn,isOnce} = item
fn(...arg)
// 用来区分是否为once,如果是once,则执行完后过滤掉,不返回
if(!isOnce) return true
return false
})
}
}
测试代码:
const fn1 = (a,b,c) => console.log(`1 ${a} ${b} ${c}`)
const fn2 = (a,b,c) => console.log(`2 ${a} ${b} ${c}`)
const fn3 = (a,b,c) => console.log(`3 ${a} ${b} ${c}`)
const fn4 = (a,b,c) => console.log(`4 ${a} ${b} ${c}`)
const bus = new EventBus()
bus.on('key', fn1)
bus.on('key', fn2)
bus.once('key', fn3)
bus.on('key', fn4)
bus.emit('key', 'a','b','c')
bus.emit('key','a','b','c')
bus.off('key', fn2)
bus.emit('key', 'a','b','c')
查看输出结果,非常简单了