用js实现发布订阅模式(详细解析版)

 实现分析:

  1. 要有个事件储存中心:用来存储 不同订阅者及对应的回调函数列表;
  2. on方法:往事件储存中心推送订阅者的回调函数;
  3. off方法:解除订阅;
  4. emit方法:派发执行同一订阅下的所有回调函数;
  5. once方法:只执行一次,执行结束后立即off掉此订阅;

代码如下:

class Eventhub{
    constructor() {
        this.eventsCenter = {};
    }
    on(key, callBack){
        // 添加订阅
        if(this.eventsCenter.hasOwnProperty(key)){
            this.eventsCenter[key].push(callBack);
        }else {
            this.eventsCenter[key] = [callBack]
        }
    }
    off(key, callBack){
        // 删除当前订阅下的 此回调函数并且在此订阅无任何回调后,删除此订阅;
        if(this.eventsCenter.hasOwnProperty(key)){
            const curCallbackList = this.eventsCenter[key]
            this.eventsCenter[key] = curCallbackList.filter(eachCallback=>eachCallback !== callBack)
            if (!curCallbackList.length) delete this.eventsCenter[key];
        }
    }
    emit(key, ...arg){
        // 派发事件,并通过apply将this,arguments传入到回调函数中
        const list = this.eventsCenter[key];
        if(list?.length){
            list.forEach(eachFun => eachFun.apply(this,[...arg]));
        }
    }
    once(key, callBack){
        // 订阅一次事件,这里注意 on 和 off要同一个引用,后续才可以将此次订阅off掉
        function fun(){
            callBack();
            this.off(key, fun)
        }
        this.on(key, fun)
    }
}

测试部分:

const demo = new Eventhub()

function test2(){
    console.log('a--> case2')
}

demo.on('a',()=>{
    console.log('a--> case1')
})
demo.on('a', test2)
// 此时a订阅下,执行case1, case2回调
demo.emit('a');
demo.off('a', test2);
// 此时a订阅下,只执行case1, case2已被解除
demo.emit('a');

demo.once('a', ()=>{
    console.log('a--> once')
})
// 此时a订阅下,执行case1, once 两次回调
demo.emit('a');

setTimeout(()=>{
    // 此时a订阅下,只执行case1, once 只执行一次
    demo.emit('a');
},1000)

以上仅为自己理解,欢迎私信沟通探讨喔!!! 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值