js发布订阅模式,记录

94 阅读2分钟

定义:发布订阅模式其实就是一种对象间的一对多的依赖关系,当一个对象的属性发生改变时,所有依赖于它的对象都会收到状态改变通知

实现思路:

  1. 定义一个对象
  2. 对象里面定义map对象,里面存储事件名称以及函数
  3. 定义on方法去订阅事件,把事件名称和函数存储到map里面
  4. 定义emit事件去发布事件
  5. 定义destory方法去销毁订阅的事件 代码片段,这个是
    把事件在on的时候传入
    const pub = {
        map: {}, //存储事件
        //发布消息的函数
        emit: function (eventName, params) {
            if (!this.map[eventName]) {
                this.map[eventName] = []
            }
            this.map[eventName].push(params)
        },
        //订阅消息的函数
        on: function (eventName, callback) {
            this.map[eventName] && this.map[eventName].forEach(params => callback(params));
        },
        // 为什么要destory
        destory: function (eventName) {
            delete this.map[eventName]
        }
    }
    pub.on('change', function (params) {
        console.log(params)
    })
    pub.emit('change', '学习')
    pub.emit('change', '快乐')

emmm,写到这里发现不对,思路不够清晰,明明是要在on里面去存储事件名以及方法,刚刚写反过来了,然后每次触发事件要写pub.on 而不是pub.emit,所以反啦反啦

重新修改

    const pub = {
        map: {}, //存储事件
        //发布消息的函数
        emit: function (eventName, ...param) {
        //循环指定事件名称下的方法依次执行,eventName就是事件名称,param为emit时候传入的参数
            this.map[eventName] && this.map[eventName].forEach(fn => fn(param));
        },
        //订阅消息的函数
        on: function (eventName, fn) {
           //把事件名以及对应的事件传入map中保存
            if (!this.map[eventName]) {
                this.map[eventName] = []
            }
            this.map[eventName].push(fn)
        },
        // 为什么要destory?
        destory: function (eventName, fn) {
        //删除指定事件名下的指定事件
            const item = this.map[eventName]
            if (!item) return
            const index = item.indexOf(fn)
            if (index !== -1) item.splice(index, 1)
        }
    }
    const change1 = function (params) {
        console.log(params)
    }
    pub.on('change', change1)
    pub.emit('change', '我超爱', '学习的')
    pub.destory('change', change1)
    pub.on('change', function (params) {
        alert(params)
    })
    pub.emit('change', '它使我', '超快乐')
    console.log(pub)

我们只需要订阅这个事件进行相应的回调函数,然后在需要触发事件的地方emit这个事件名称,参数。