发布——订阅模式

发布——订阅模式

发布—订阅模式在vue和node.js中广泛使用。

发布—订阅模式的需要 发布者(对象)、订阅者(函数)、订阅函数、触发函数

在vue中有这种代码:this.$on(); this.$emit();

在node.js中有这种代码:

var events = require('events'); 
var emitter = new events.EventEmitter(); 
emitter.on('someEvent', ()=>{}); 
emitter.on('someEvent', ()=>{}); 
emitter.emit('someEvent', 'arg1 参数', 'arg2 参数'); 

在原生js事件监听中有这种:

button.addEventListener('click',()=>{});

以上都是使用的发布订阅模式。

下面模拟一个事件监听器:

一 首先声明 发布者

var salesOffices = {};//发布者
salesOffices.clientList = [];//缓存列表,存放订阅者的回调函数
salesOffices.listen = function(sub){
    this.clientList.push(sub);// 订阅的消息添加进缓存列表
}
salesOffices.trigger = function() {
    this.clientList.forEach((sub) => {
        sub.apply(this,arguments);
    })
}

二 声明 订阅者 

/* 声明订阅者 */
function sub1(msg) {
    console.log("我是订阅者sub1",msg);
}
function sub2(msg) {
    console.log("我是订阅者sub2",msg);
}
function sub3(msg) {
    console.log("我是订阅者sub3",msg);
}

三 订阅 订阅者

/* 添加订阅者 */
salesOffices.listen(sub1);
salesOffices.listen(sub2);
salesOffices.listen(sub3);

四 触发 订阅者函数

/* 触发发布 */
salesOffices.trigger("我是发布的消息");

现在发布者发布的消息,全部订阅者都收的到,但是接下来我们要实现的是让不同的订阅者接受特定的消息,相当于click事件只能触发订阅了click事件的处理函数。并且添加了 移除订阅者 和 移除某类事件的订阅者 的函数。

var salesOffices = {};//发布者
salesOffices.clientList = {};//缓存列表,存放订阅者的回调函数
salesOffices.listen = function(key,sub){
    if(!(this.clientList[key])){
        this.clientList[key] = [];
    }
    this.clientList[key].push(sub);// 订阅的消息添加进缓存列表
}
salesOffices.trigger = function() {//发布消息
    var key = Array.prototype.slice.call(arguments,0)[0];
    //提高性能
    if(!this.clientList[key] || this.clientList[key].length == 0){
        return
    }
    this.clientList[key].forEach((sub) => {
        sub.apply(this,arguments);
    })
}
//移除订阅者
salesOffices.removeSubscriber = function(key,sub) { 
    if(!this.clientList[key] || this.clientList[key].length == 0){
        return
    }
    const index = this.clientList[key].findIndex((element) => {return element == sub});
    this.clientList[key].splice(index,1);
}
/* 移除一类事件的所有订阅者 */
salesOffices.removeAllSubscribers = function(key) {
    if(!this.clientList[key] || this.clientList[key].length == 0){
        return
    }
    delete this.clientList[key];
}
/* 声明订阅者 */
function sub1(key,msg) {
    console.log("我是订阅者sub1",key,msg);
}
function sub2(key,msg) {
    console.log("我是订阅者sub2",key,msg);
}
function sub3(key,msg) {
    console.log("我是订阅者sub3",key,msg);
}
/* 添加订阅者 */
salesOffices.listen('click',sub1);
salesOffices.listen('click',sub2);
salesOffices.listen('mouseover',sub3);
/* 触发发布 */
salesOffices.trigger('click',"我是发布的消息");//sub3虽然被订阅,但是不会被执行
salesOffices.removeSubscriber('click',sub1);
salesOffices.trigger('click',"我是发布的消息");
salesOffices.removeAllSubscribers('click');
salesOffices.trigger('click',"我是发布的消息");

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值