实战 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')
贡献者: mankueng