设计模式-发布订阅

99 阅读1分钟
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
</head>
<body>
<h1>test</h1>
<script>
    /*
发布订阅模式
区间:观察者模式,发布订阅模式,消息系统,消息机制,自定义事件
4个点
1个massage属性
3个方法_on,_off,_emit
观察vue里面的方法
*/

class Observer{
    constructor() {
        this.massage = {};
    }
    // new的实例可以新增事件订阅
    _on(type, fn) {
        if(!this.massage[type]) {
            this.massage[type] = [];
        }else {
            this.massage[type].push(fn);
        }
    }
    //new的实例 可以取消事件订阅
    _off(type, fn) {
        if(!this.massage[type]) {
            return;
        }
        if(!fn) {
            this.massage[type] = undefined;
        }else {
            this.massage[type] = this.massage[type].filter((item)=>{
                return item !== fn;
            })
        }
    }
    //
    //Observer的实例触发adda的事件,相当于发布订阅, 由于_on对于‘adda’绑定了一系列事件(handlead,handleb,handlec),所以就可以在emit里面直接触发
    _emit(type) {
        if(!this.massage[type]) {
            return;
        }
        this.massage[type].forEach((item)=> {
            item();
        }) 
    }
}

function handlead() {
    let name = 'a订阅';
    console.log('a订阅');
}
function handleb() {
    let name = 'b订阅';
    console.log('b订阅');
}
function handlec() {
    console.log('c订阅');
}

let person = new Observer();
person._on('adda', handleb);

person._on('adda', handlead);
person._on('adda', handleb);
person._on('adda', handleb);

person._on('adda', handlec);

person._on('addb', handleb);

// person._off('adda');
// person._off('adda', handlec);

person._emit('adda');


console.log(person);
</script>

</body>
</html>