JS观察者模式 详解

本文介绍了一个简单的事件总线实现方案,通过定义Observer类来管理事件的订阅、发布及取消,适用于小型应用或学习场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 我们要有一个观察者(这里抽象为一个对象 {}

需要有一个属性,存放消息的盒子(把你绑定的所有事件放在里面)

需要一个 on 方法,用于添加事件

需要一个 emit 方法,用于发布事件(触发)

需要一个 off 方法,把已经添加的方法取消

    // 定义一个class类
    class observer {
        constructor() {
            // 存放消息的盒子,把绑定的所有事件放在里面
            this.box = {}
        }
        // on方法,用于添加事件
        on(type, fn) { // type事件类型,fn事件处理函数
            // 添加时先判断盒子里有没有这个事件类型
            if(!this.box[type]) {
                // 如果没有那么需要新增这个类型,当键存储在box对象,键对应的是一个数组,里面是不同的事件函数(相当于多少个订阅的人)
                this.box[type] = [fn]
            }else {
                // 如果已经有了,那么直接把这个事件函数放进数组去(相当于把这个人加进去)
                this.box[type].push(fn)
            }
        }
        // emit方法,用于发布事件(就是让订阅好的事件执行)
        emit(type, ...arr) { // type事件类型,arr给事件处理函数传递参数,由于不知道会传递多少参数,所以使用...运算符
            // 如果box里面压根没有这个事件类型,那就不需要执行了,直接return
            if(!this.box[type]) return
            // 如果有那么执行事件函数
            this.box[type].forEach(item => {
                // item() 不改变事件this直接调用
                // 调用对应type事件类型,数组里面的方法,顺便改变事件函数内this为当前位置this,并将参数传递入事件函数
                item.call(this,arr)
            })
        }
        // off方法,移除事件函数
        off(type, fn) { // type事件类型,fn事件处理函数
            // 如果压根没有这个事件类型,删除个毛,直接return
            if(!this.box[type]) return
            // 如果有这个事件类型,遍历事件类型对应的数组
            for(let i=0; i<this.box[type].length; i++) {
                // 如果数组中有需要删除的事件函数
                if(this.box[type][i] == fn) {
                    // 使用数组的splice删除i下标开始的1个数据
                    this.box[type].splice(i,1)
                }
            }
        }
        // clear方法,删除一类数据
        clear(type) { // type事件类型
            // 如果压根没有这个事件类型,删除个毛,直接return
            if(!this.box[type]) return
            // 直接删除box的type键
            delete this.box[type]
        }
        // empty方法,清空数据
        empty() {
            if(this.box) this.box = {}
        }
    }

    // 使用观察者模式操作
    var obs = new observer() // 实例化对象
    // 准备传入的事件处理函数
    function f1(a) {
        console.log('hello')
    }
    function f2(a) {
        console.log('world')
    }
    function f3(a) {
        console.log(a)
    }
    function f4(a) {
        console.log(a)
    }

    // 订阅事件
    obs.on('ssr',f1)
    obs.on('sr',f2)
    obs.on('ssr',f3)
    obs.on('sr',f4)
    // 发布事件
    obs.emit('ssr',100,200,300)
    obs.emit('sr',400,500,600)
    // 移除事件函数
    obs.off('ssr',f1)
    obs.off('sr',f4)
    // 删除一类数据
    obs.clear('ssr')
    // 清空数据
    obs.empty()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值