node中事件(events)模組一些用法和原理

周必川發表於2018-03-26

//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;

相關文章