ts实现一个发布订阅模式

394 阅读2分钟

发布订阅模式有4个方法,存储结构是一个对象键是表示类一类,值是一个对象,每一项都是一个方法

1.on方法将某给对象属性,数组添加一个方法(将消息收集到一个数组里面)

2.emit方法将对象属性的数组中的方法遍历执行(执行对象的key对应的方法)

3.off删除对象属性数组中的某一个方法(找到相同的方法并删除)

4.once和on一样,只是添加的方法emit只能执行一次,执行一次后销毁(定义一个临时变量进行on然后off,只触发once打印一次)

image.png

interface EventFace {

    // 定义类

    on: (TypeName: string, callback: Function) => void; //订阅消息

    emit: (TypeNam: string, ...args: Array<any>) => void; // 发布消息

    off: (TypeName: string, callback: Function) => void; //删除指定函数

    once(TypeName: string, callback: Function): void; // 只执行一次,删除指定函数

    //on(Ms:string,Fun:Function):void 接口定义函数

}

interface List {

    //定义一个属性例如:post,值为【】,将on的都push进去

    [key: string]: Array<Function>

}

class Dispatch implements EventFace {

    list: List

    constructor() {

        // 初始化一个对象

        this.list = {}

    }

    // 将其信息收集起来

    on(TypeName: string, callback: Function) {

        const fn = this.list[TypeName] || []

        fn.push(callback)

        this.list[TypeName] = fn

    }

    // 发布消息,也就是执行on的方法

    emit(TypeName: string, ...args: Array<any>) {

        // 判断是不是有emit的post这个对应的方法去执行

        const eventName = this.list[TypeName]

        if (eventName) {

            eventName.forEach(fn => {

                fn.apply(this, args)

            })

        } else {

            console.log(`名称错误${TypeName}`)

        }

  


    }

    // 将其方法fn卸载掉

    off(TypeName: string, callback: Function) {

        const eventName = this.list[TypeName]

        if (eventName && callback) {//判断有没有这个对象属性和函数

            let index = eventName.findIndex(fns => fns === callback)

            eventName.splice(index, 1)

        } else {

            console.log(`名称错误${TypeName}`)

        }

    }

    // 只执行一次

    once(TypeName: string, callback: Function): void {

        // 定义一个临时变量,和on一样,只是它添加的只能使用一次

        let decor = (...args: Array<any>) => {

            console.log('args', args)

            callback.apply(this, args)// 执行然后删除

            this.off(TypeName, decor)// 删除方法

        }

        // 使用on添加到,list中

        this.on(TypeName, decor);

    }

  


}

  


const o = new Dispatch()

  


o.on('post', (...args: Array<any>) => {

    console.log(args, 1)

})

// o.off('post', (...args: Array<any>) => {

//     console.log(args, 1)

// })

// o.on('post', (...args: Array<any>) => {

//     console.log(args, 2)

// })

  


o.once('post', (...args: Array<any>) => {

    console.log(args, "once")

})

  


 o.emit('post', 1, false, { name: '发布订阅模式' })

 o.emit('post', 2, true, { name: '发布订阅模式' })

  


export {

    o

}