發(fā)布-訂閱模式/觀察者模式
發(fā)布-訂閱模式也叫觀察者模式,這是一個一對多的關系,可以多個訂閱者訂閱同一個事件,當事件觸發(fā)時就會通知訂閱者去執(zhí)行訂閱時綁定的程序;
我舉個例子來解釋一下:
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酒店過來喝酒,這個過程就是發(fā)布事件
A.emit("結婚");
以下是我的實現(xiàn)過程:
class EventEmitter {
constructor(){
this._count=null;
}
//訂閱事件
on(type,callBack,flag){
//創(chuàng)建_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類型,則執(zhí)行newListener對應的函數(shù)
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);
}
//發(fā)布事件
emit(type,...args){
if(this._events[type]){
this._events[type].forEach(fn => {
fn.call(this,...args)
});
}
}
// 獲取當前type事件的數(shù)組對象
listeners(type){
return this._events[type]||[];
}
// 訂閱事件并在第一時間觸發(fā)
prependListener(type,callBack){
this.on(type,callBack,true);
}
// 訂閱一次性事件并在第一時間觸發(fā)
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事件所有的執(zhí)行函數(shù)
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;