//node中的事件(evets)模組的用法和原理實現
//1、基本用法on、emit let EventEmitter=require("./events"); function Office(){
}; let util=require("util"); util.inherits(Office,EventEmitter)//相當於Office.prototype.proto= EventEmitter.prototype; let office = new Office(); office.on("paper",user1); function user1(){ console.log("user1訂閱了報紙") } office.on("paper",user2); function user2(){ console.log("user2訂閱了報紙") } office.emit("paper"); //user1訂閱了報紙 //user2訂閱了報紙
//1實現的原理.on和emit的實現原理和釋出訂閱一樣,用一個空的物件的key儲存使用者訂閱的內容,value儲存訂閱此內容的使用者{"paper":[user1,user2]}
function EventEmitter(){ this._events=Object.create(null);//{}中有原型鏈,上面建立的是沒有原型鏈的物件 } EventEmitter.prototype.on=function(type,callback){//物件儲存訂閱的內容 if(!this._events){ this._events=Object.create(null);//原型指向某函式時,讓這個函式中也有這個物件 } if(this._events[type]){ this._events[type].push(callback);//有paper說明之前有使用者,有使用者說明有陣列,直接push }else{ this._events[type]=[callback];//第一個使用者用陣列存起來 } } EventEmitter.prototype.emit=function(type){//遍歷物件中儲存的方法 if(this._events[type]){//只有訂閱這個事件才執行 this._events[type].forEach(listener =>{ listener.call(this); }) } } module.exports=EventEmitter;
//2、帶引數的on、emit
let EventEmitter=require("events"); function Office(){
}; let util=require("util"); util.inherits(Office,EventEmitter) let office = new Office(); office.on("paper",user1); function user1(data){ console.log("user1報紙:"+data) } office.on("paper",user2); function user2(data){ console.log("user2報紙:"+data) } office.emit("paper","這裡是報社發出的訊息");
//user1報紙:這裡是報社發出的訊息 //user2報紙:這裡是報社發出的訊息
//2.實現的原理
function EventEmitter(){ this._events=Object.create(null); } EventEmitter.prototype.on=function(type,callback){ if(!this._events){ this._events=Object.create(null); } if(this._events[type]){ this._events[type].push(callback); }else{ this._events[type]=[callback]; } } EventEmitter.prototype.emit=function(type,flag){ if(this._events[type]){ this._events[type].forEach(listener =>{ listener.call(this,flag);//on中的函式上新增引數 }) } } module.exports=EventEmitter;
//3、removeListener刪除
let EventEmitter=require("./events"); function Office(){
}; let util=require("util"); util.inherits(Office,EventEmitter) let office = new Office(); office.on("paper",user1); function user1(data){ console.log("user1報紙:"+data) } office.on("paper",user2); function user2(data){ console.log("user2報紙:"+data) } office.emit("paper","這裡是報社發出的訊息"); office.removeListener("paper",user1); office.emit("paper","這裡是報社發出的訊息2"); //user1報紙:這裡是報社發出的訊息 //user2報紙:這裡是報社發出的訊息 //user2報紙:這裡是報社發出的訊息2
//3.removeListeren實現的原理:找到相應的陣列項刪除
function EventEmitter(){ this._events=Object.create(null); } EventEmitter.prototype.on=function(type,callback){ if(!this._events){ this._events=Object.create(null); } if(this._events[type]){ this._events[type].push(callback); }else{ this._events[type]=[callback]; } } EventEmitter.prototype.removeListener=function(type,callback){ if(this._events[type]){//有此事件才進入 this._events[type]=this._events[type].filter(function(listener){ return listener != callback;//只有不和需要移除的函式相等才返回 }) } } EventEmitter.prototype.emit=function(type,flag){ if(this._events[type]){ this._events[type].forEach(listener =>{ listener.call(this,flag);//on中的函式上新增引數 }) } } module.exports=EventEmitter;
//4、once只訂閱一次
let EventEmitter=require("./events"); function Office(){
}; let util=require("util"); util.inherits(Office,EventEmitter) let office = new Office(); office.once("paper",user1); function user1(data){ console.log("user1報紙:"+data) } office.on("paper",user2); function user2(data){ console.log("user2報紙:"+data) } office.emit("paper","這裡是報社發出的訊息"); office.emit("paper","這裡是報社發出的訊息2");
//user1報紙:這裡是報社發出的訊息 //user2報紙:這裡是報社發出的訊息 //user2報紙:這裡是報社發出的訊息2
//4.once實現的原理:實現一次後清空
function EventEmitter(){ this._events=Object.create(null); } EventEmitter.prototype.on=function(type,callback){ if(!this._events){ this._events=Object.create(null); } if(this._events[type]){ this._events[type].push(callback); }else{ this._events[type]=[callback]; } } EventEmitter.prototype.removeListener=function(type,callback){ if(this._events[type]){ this._events[type]=this._events[type].filter(function(listener){ return listener != callback && listener.l !==callback;//刪除時把有l的也刪除 }) } } EventEmitter.prototype.once=function(type,callback,flag){ function wrap(){//確保這個在on之後執行 callback(...arguments)//argument是回撥函式的引數 this.removeListener(type,wrap);//陣列中移除掉 } wrap.l=callback//避免removeListener刪除不了 this.on(type,wrap,flag);//先執行一次 } EventEmitter.prototype.emit=function(type,flag){ if(this._events[type]){ this._events[type].forEach(listener =>{ listener.call(this,flag);//on中的函式上新增引數 }) } } module.exports=EventEmitter;
//5.addListener用法同on
//5的原理
EventEmitter.prototype.addListener=EventEmitter.prototype.on;//將on的原型指向addlistener
//6.newListener監聽之後的事件
let EventEmitter=require("./events"); function Office(){
}; let util=require("util"); util.inherits(Office,EventEmitter) let office = new Office(); office.on("paper",user1); function user1(data){ console.log("user1報紙:"+data) } office.on("newListener",function(data){ console.log(data) }) office.on("paper1",user2); function user2(data){ console.log("user2報紙:"+data) } office.emit("paper","這裡是報社發出的訊息"); //paper1 //user1報紙:這裡是報社發出的訊息
//6.newListener實現的原理:排除在newlistener之前和自己本身的事件,將事件作為引數傳給回撥函式
function EventEmitter(){ this._events=Object.create(null); } EventEmitter.prototype.on=function(type,callback){
if(!this._events){
this._events=Object.create(null);
}
if(type !=="newListener"){//排除type為newListener的情況
this._events["newListener"] //排除type在newListener之前的情況
&& this._events["newListener"].forEach(listener =>{
listener(type)//將事件作為引數傳出去
})
}
if(this._events[type]){
this._events[type].push(callback);
}else{
this._events[type]=[callback];
}
複製程式碼
} EventEmitter.prototype.removeListener=function(type,callback){ if(this._events[type]){ this._events[type]=this._events[type].filter(function(listener){ return listener != callback && listener !==callback; }) } } EventEmitter.prototype.once=function(type,callback,flag){ function wrap(){ callback(...arguments) this.removeListener(type,wrap); } wrap.l=callback; this.on(type,wrap,flag); } EventEmitter.prototype.addListener=EventEmitter.prototype.on;//將on的原型指向addlistener EventEmitter.prototype.emit=function(type,flag){ if(this._events[type]){ this._events[type].forEach(listener =>{ listener.call(this,flag); }) } } module.exports=EventEmitter;
//7.defaultMaxListeners預設事件的最大值
let EventEmitter=require("./events"); console.log(EventEmitter.defaultMaxListeners)
//10
//8.listener監聽事件
let EventEmitter=require("./events"); function Office(){
}; let util=require("util"); util.inherits(Office,EventEmitter) let office = new Office(); office.on("paper",user1); function user1(data){ console.log("user1報紙:"+data) } office.on("paper",user2); function user2(data){ console.log("user2報紙:"+data) } console.log(office.listeners('paper')) //[ [Function: user1], [Function: user2] ]
//8.listener實現的原理裡:物件中找到指定的事件,將事件下的陣列返回
function EventEmitter(){ this._events=Object.create(null); } EventEmitter.defaultMaxListeners="10" EventEmitter.prototype.on=function(type,callback){
if(!this._events){
this._events=Object.create(null);
}
if(type !=="newListener"){
this._events["newListener"]
&& this._events["newListener"].forEach(listener =>{
listener(type)
})
}
if(this._events[type]){
this._events[type].push(callback);
}else{
this._events[type]=[callback];
}
複製程式碼
} EventEmitter.prototype.removeListener=function(type,callback){ if(this._events[type]){ this._events[type]=this._events[type].filter(function(listener){ return listener != callback && listener !==callback; }) } } EventEmitter.prototype.listeners=function(type){ return this._events[type];//返回這個事件下的陣列 } EventEmitter.prototype.once=function(type,callback,flag){ function wrap(){ callback(...arguments) this.removeListener(type,wrap); } wrap.l=callback; this.on(type,wrap,flag); } EventEmitter.prototype.addListener=EventEmitter.prototype.on;//將on的原型指向addlistener EventEmitter.prototype.emit=function(type,flag){ if(this._events[type]){ this._events[type].forEach(listener =>{ listener.call(this,flag); }) } } module.exports=EventEmitter;