const eventBus = {
// 创建一个订阅对象
arrays: {},
// 添加订阅
on: function(type, fn) {
this.arrays[type] = this.arrays[type] || []
let flag = true
for(let i = 0; i < this.arrays[type].length; i++) {
if(this.arrays[type][i] === fn) {
flag = false
break;
}
}
if(flag) this.arrays[type].push(fn)
},
// 发布订阅过的方法
emit: function(type, ...args) {
this.arrays[type] = this.arrays[type] || []
if(this.arrays[type].length) {
this.arrays[type].forEach(callback => {
callback(...args)
})
}
},
// 取消订阅
off: function(type, fn) {
let args = Array.from(arguments)
if(args.length === 0) { // 取消所有订阅方法
this.arrays = {}
}else if(args.length === 1) { // 取消某一事件的所有方法
if(!this.arrays[type]) return
this.arrays[type] = []
}else if(args.length === 2) {
if(!this.arrays[type]) return
/**
* 由于可能某type下有多个订阅
* 删除数组自身元素时,自身长度和下表会发生变化
* 所以采用逆向循环
*/
for(let i = this.arrays[type].length - 1; i >= 0; i--) {
if(this.arrays[type][i] === fn) {
// fn是引用类型,比较的是引用地址
this.arrays[type].splice(i, 1)
}
}
}
},
}
// 订阅
eventBus.on('click', function(data ,num1, num2, num3) {
console.log(data, 'data----->>>')
console.log(num1, 'num1----->>>')
console.log(num2, 'num2----->>>')
console.log(num3, 'num3----->>>')
})
eventBus.on('click', function(data,num1, num2, num3) {
console.log(data,'data--->>>')
console.log(num1, 'num1----->>>')
console.log(num2, 'num2----->>>')
console.log(num3, 'num3----->>>')
})
eventBus.on('test', function(data) {
console.log(data,'试一试test---->>>')
})
// 取消订阅
eventBus.off('test')
// 发布
eventBus.emit('click', '触发click事件', 1, 2,3)
eventBus.emit('test', '触发test事件')
手写一个基于发布订阅模式的简单js事件
于 2022-03-16 10:44:06 首次发布