发布-订阅模式/观察者模式
发布-订阅模式也叫观察者模式,这是一个一对多的关系,可以多个订阅者订阅同一个事件,当事件触发时就会通知订阅者去执行订阅时绑定的程序;
我举个例子来解释一下:
A同学想在结婚的时候邀请好友B、C、D、E、F、G…来喝喜酒,这个邀请的名单其实就是订阅事件
class Person extends EventEmitter{
constructor(){
super();
}
}
let A= new Person();
function drinkFn(){
console.log( `xxxx年xx月xx日来xx大酒店和我的喜酒!`)
}
A.on("结婚",drinkFn);
等到A同学要结婚的时候,他就会去通知他的好友XXX时间XX酒店过来喝酒,这个过程就是发布事件
A.emit("结婚");
以下是我的实现过程:
class EventEmitter {
constructor(){
this._count=null;
}
//订阅事件
on(type,callBack,flag){
//创建_events对象
if(!this._events){
this._events=Object.create(null);
}
// 判断_events对象是否有type属性
if(this._events[type]){
if(flag){
this._events[type].unshift(callBack)
}else{
this._events[type].push(callBack)
}
}else{
this._events[type]=[callBack]
}
//type如果不是newListener类型,则执行newListener对应的函数
if(type!=="newListener"){
this._events["newListener"]&&this._events["newListener"].forEach(fn=>{
fn(type,callBack);
})
}
// 超出最大绑定事件限制提示
if(this._events[type].length>=this.getMaxListeners()){
console.log("超出最大绑定事件限制")
}
}
//订阅一次性事件
once(type,callBack,flag){
function warp(...argments){
callBack(...argments);
this.removeListener(type,callBack)
}
warp.cb=callBack;
this.on(type,warp,flag);
}
//发布事件
emit(type,...args){
if(this._events[type]){
this._events[type].forEach(fn => {
fn.call(this,...args)
});
}
}
// 获取当前type事件的数组对象
listeners(type){
return this._events[type]||[];
}
// 订阅事件并在第一时间触发
prependListener(type,callBack){
this.on(type,callBack,true);
}
// 订阅一次性事件并在第一时间触发
prependOnceListener(type,callBack){
this.once(type,callBack,true);
}
// 获取当前实例所有的事件类型
eventNames(){
return Object.keys(this._events)
}
// 获取当前type事件类型的长度
listenerCount(type){
if(this._events[type]){
return this._events[type].length
}else{
return 0
}
}
// 移除type事件所有的执行函数
removeListener(type,callBack){
if(this._events[type]){
this._events[type]=this._events[type].filter(fn=>{
return callBack!=fn&&fn.cb!=callBack
})
}
}
// 移除实例上所有的事件
removeAllListeners(){
this._events=Object.create(null)
}
// 获取当前实例的最大事件绑定限制
getMaxListeners(){
return this._count ? this._count :EventEmitter.defaultMaxListeners;
}
// 设置当前实例的最大事件绑定限制
setMaxListeners(n){
this._count=n;
}
}
// 设置默认的最大事件绑定限制
EventEmitter.defaultMaxListeners=10;
module.exports=EventEmitter;