js实现发布订阅模式

发布订阅模式指的是希望接收通知的对象(Subscriber)基于一个主题通过自定义事件订阅主题,被激活事件的对象(Publisher)通过发布主题事件的方式通知各个订阅该主题的 Subscriber 对象。

订阅发布模式需要有: 订阅、发布、移除订阅三个方法;

class PubSub{
    constructor(){
        this.handleBars= {}; // 保存监听事件
    }
    // 订阅
    subscribe(eventName,handle){
        try {
            if (!this.handleBars.hasOwnProperty(eventName)){
                this.handleBars[eventName] = [];
            } 
            if (typeof handle == 'function') {
                this.handleBars[eventName].push(handle);
            } else {
                throw new Error(`你需要给${eventName}事件添加回调方法`);
            }
        } catch (error) {
            console.warn(error);
        }
    }
    // 发布
    publish(eventName,...arg){
        try {
            if (this.handleBars.hasOwnProperty(eventName)) {
                this.handleBars[eventName].map(item=>{
                    item.apply(null,arg)
                })
            } else {
                throw new Error(`${eventName}事件未被注册`);
            }
        } catch (error) {
            console.warn(error);
        }
    }
    // 移除订阅
    unSubscribe(eventName,handle){
        try {
            if (this.handleBars.hasOwnProperty(eventName)){
                this.handleBars[eventName].map((item,index)=>{
                    if (item === handle) {
                        console.log(item);
                        this.handleBars[eventName].splice(index,1)
                    }
                })
            }
        } catch (error) {
            console.warn(error);
        }
    }
}
// 实例化
const sub = new PubSub();

// 订阅的回调方法
function func1(type){
    console.log('===type=1==',type);
}
function func2(type){
    console.log('===type=2==',type);
}
function func3(type,data){
    console.log('===type===',type,'===data===',data);
}
// 订阅事件
sub.subscribe('ready',func1)
sub.subscribe('ready',func2)
sub.subscribe('complate',func3)

setTimeout(()=>{
    // 触发订阅事件
    sub.publish('ready','ready') 
    sub.publish('complate','complate','哈哈哈')
    console.log(sub.handleBars);

    // 移除订阅的ready事件func1回调
    sub.unSubscribe('ready',func1);
    console.log(sub.handleBars);

},1000)

输出结果如下:

1 ===type=1== ready
2 ===type=2== ready
3 ===type=== complate ===data=== 哈哈哈
4 { ready: [ [Function: func1], [Function: func2] ], complate: [ [Function: func3] ] }
5 [Function: func1]
6 { ready: [ [Function: func2] ],  complate: [ [Function: func3] ] }
下面这三行是添加订阅,并且"ready"订阅了两次,添加了两个不同的回调。
sub.subscribe('ready',func1)
sub.subscribe('ready',func2)
sub.subscribe('complate',func3)

输出的结果中也可以看到,通过publish方法发布后,三个订阅全部生效,回调方法执行。

1 ===type=1== ready
2 ===type=2== ready
3 ===type=== complate ===data=== 哈哈哈

随后执行unSubscribe方法,取消订阅过的方法:

如下输出,第四行为添加订阅后的所监听的方法,第5行为通过sub.unSubscribe('ready',func1);要移除的func1,第6行为移除后的订阅方法。

4 { ready: [ [Function: func1], [Function: func2] ], complate: [ [Function: func3] ] }
5 [Function: func1]
6 { ready: [ [Function: func2] ],  complate: [ [Function: func3] ] }]]

你可能感兴趣的:(js实现发布订阅模式)