发布者订阅者模式,看这一篇就够辣!

490 阅读1分钟

发布者订阅者模式相比于观察者模式多了一层事件调度中心。主要有发布事件,触发事件,删除事件等功能。

ES5原型写法

function EventBus() {
            //定义一个事件容器
            this.eventList = {};

            //事件添加方法,参数有事件名和事件方法
            EventBus.prototype.listen = function (event, callback) {
                //判断有没有事件容器,没有则创建一个新事件容器
                if (!(event in this.eventList)) {
                    this.eventList[event] = []
                };
                this.eventList[event].push(callback);
            }

            //触发事件 两个参数(事件名,参数)
            EventBus.prototype.emit = function (event, ...args) {
                //若没有注册事件则抛出错误
                if (!(event in this.eventList)) {
                    throw new Error('未注册事件')
                }

                //触发事件
                this.eventList[event].forEach(fn => { fn(...args) });
            }


            // 移除事件 (事件名 删除的方法 若无第二个参数则删除该事件的订阅和发布)
            EventBus.prototype.delete = function (event, callback) {
                if (!this.eventList[event]) {
                    throw new Error('无效事件')
                }
                if (this.eventList[event]) {
                    let index = this.eventList[event].indexOf(callback)
                    //有callback方法,删除方法
                    if (index !== -1) {
                        this.eventList[event].splice(index, 1)
                    }
                    //没有callback方法,直接删除事件
                    if (arguments.length === 1) {
                        delete this.eventList[event]
                    }
                }
            }
        }

class写法

class EventBus {
    constructor() {
        this.eventList = {};
    }

    listen(event, cb) {
        if (!this.eventList[event]) {
            this.eventList[event] = [];
        }
        this.eventList[event].push(cb);
    }

    emit(event, ...args) {
        if (!this.eventList[event]) {
            throw Error('没有注册事件');
        }
        this.eventList[event].forEach(fn => fn(...args));
    }

    delete(event, cb) {
        if (!this.eventList[event]) {
            throw new Error('无效事件');
        }
        if (this.eventList[event]) {
            const index = this.eventList[event].indexOf(cb);
            if (index !== -1) {
                this.eventList[event].splice(index, 1);
            }

            if (arguments.length === 1) {
                delete this.eventList[event];
            }
        }
    }
}

测试

let a = new EventBus();
        let foo1 = function (msg) {
            console.log(msg);
        }
        let foo2 = function (msg) {
            console.log('fsaf');
        }
        let foo3 = function (a) {
            console.log('1111');
        }

        a.listen('sayHi', foo1)
        a.listen('haha', foo2)
        a.listen('sayHi', foo3)


        a.emit('sayHi', Math.random())
        a.emit('sayHi', ['214214', '12312'])
        a.emit('haha', 1241)

        a.delete('sayHi', foo3)


        console.log(`############################`)

        a.emit('sayHi', Math.random())
        a.emit('sayHi', ['214214', '12312'])
        a.emit('haha', 1241)

image.png


记录记录!