typescript 实现发布订阅模式

309 阅读1分钟

具体实现

// event中定义4个方法
interface Event {
    on: (name:string, cb:Function) => void,
    emit: (name:string, ...args:Array<any>) => void,
    off: (name:string, cb:Function) => void,
    once: () => once
}
// List用来存储变量 键值对+名称
/*
    {
        事件名xxx: ['a','b','c']
    }
*/
interface List {
    [key:string]:Array<Function>
}

// disPatch 类具体实现4个方法 on emit off once
// disPatch 类中实现list 变量用来存储事件
class DisPatch implements Event{
    list: List
    constructor() {
        this.list = {}
    }
    
    on:(name:string, cb:Function){
        if(!this.list[name]) {
            this.list[name] = []
        }
        this.list[name].push(cb)
    }
    emit:(name:string, ...args:Array<any>){
        if(!this.list[name]) {
            console.error("该事件不存在,下次再来")
        } else {
            this.list[name].forEach(cb=>{
                cb.apply(this,args)
            })
        }

    }
    off(name:string, cb:Function){
        let events = this.list[name]
        if(events && cb){
          let index = events.find(event=> event === cb)
          index && events.splice(index,1)
        } else {
          console.log("该事件已被删除")
        }
    }
    // 监听一次 => 调用完即删除 => 内部先执行on =>on里面包括cb和off事件 => 添加后再删除
    once(name:string,cb:Function){
        let onceEvent = (...args: Array<any>)=>{
            cb.apply(this, args)
            this.off('name',onceEvent)
        }
        this.on(name,onceEvent)
    }
}

调用例子

const o = new Dispatch
const fn = ()=>{console.log(111)}
o.on('post',fn)

o.off('post',fn)
o.emit('post',1,false,{name: '小满'})