0
点赞
收藏
分享

微信扫一扫

手写一个基于发布订阅模式的简单js事件

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事件')


举报

相关推荐

0 条评论