实战 TS 编写发布订阅模式
概述
什么是发布订阅模式,其实小伙伴已经用到了发布订阅模式例如 addEventListener,Vue evnetBus
都属于发布订阅模式
简单来说就是 你要和 大傻 二傻 三傻打球,大傻带球,二傻带水,三傻带球衣。全都准备完成后开始打球。
具体代码
- on 订阅/监听
- emit 发布/注册
- once 只执行一次
- off 解除绑定
interface EventFace {
on: (name: string, callback: Function) => void
emit: (name: string, ...args: Array<any>) => void
off: (name: string, fn: Function) => void
once: (name: string, fn: Function) => void
}
interface List {
[key: string]: Array<Function>
}
class Dispatch implements EventFace {
list: List
constructor() {
this.list = {}
}
on(name: string, callback: Function) {
const callbackList: Array<Function> = this.list[name] || []
callbackList.push(callback)
this.list[name] = callbackList
}
emit(name: string, ...args: Array<any>) {
let eventName = this.list[name]
if (eventName) {
eventName.forEach((fn) => {
fn.apply(this, args)
})
} else {
console.error('该事件未监听')
}
}
off(name: string, fn: Function) {
let eventName = this.list[name]
if (eventName && fn) {
let index = eventName.findIndex((fns) => fns === fn)
eventName.splice(index, 1)
} else {
console.error('该事件未监听')
}
}
once(name: string, fn: Function) {
let decor = (...args: Array<any>) => {
fn.apply(this, args)
this.off(name, decor)
}
this.on(name, decor)
}
}
const o = new Dispatch()
o.on('abc', (...arg: Array<any>) => {
console.log(arg, 1)
})
o.once('abc', (...arg: Array<any>) => {
console.log(arg, 'once')
})
// let fn = (...arg: Array<any>) => {
// console.log(arg, 2)
// }
// o.on('abc', fn)
// o.on('ddd', (aaaa: string) => {
// console.log(aaaa)
// })
//o.off('abc', fn)
o.emit('abc', 1, true, 'mk')
o.emit('abc', 2, true, 'mk')
// o.emit('ddd', 'addddddddd')