preface
Node.js has been used for a long time, but the principle has always been ambiguous. Recently, I read node.js and realized that the event loop is the core of the whole, so I began to understand its principle and part of the implementation of the Events module.
The basic principles of the book online said much better than ME, I will not repeat. After understanding the basics, I tried to implement one myself. In the implementation of reference to a lot of other people written and the comments section of the improvement of the description, if you want to achieve their own I summarized as the following points:
- Properties: _events _eventsCount
- Methods: on, off, once, emit, removeAllListeners
_eventsCount counts all events. The on method binds the event and takes an event name type and a listener as arguments. The off method removes a listener. Once takes the event name type and listener as arguments. Once is similar to ON, but the listener added by once is executed only once. Emit trigger events can trigger removeAllListeners to removeAllListeners of the event given the event name.
Custom implementation code
The specific code is shown below, in order to consolidate the original basic syntax, I did not use ES6 syntax, but used the prototype method, probably not good writing, will have a look.
/** * Implement EnvetEmitter, in order to consolidate JS, try to use the old syntax, Let /const * _events * _eventsCount event statistics * _maxListeners Maximum number of events * on addEventListener * once * OFF removeListener * emit * removeAllListeners */
function EventEmitter(options={}){
this._events={};
this._eventsCount=0;
var _DEFAULT_MAX_LISTENERS=10; // The maximum number of events allowed
this._maxListeners=options.maxListeners? options.maxListeners:_DEFAULT_MAX_LISTENERS; }// Add a listener
EventEmitter.prototype.on=function(type,listener){
if(!this._events){
this._events={}; // Make sure that subclass inheritance is not null
}
//exit the event?
if(this._events[type]){
this._events[type].push(listener);
if(!this._maxListeners! =0 && this._events[type].length>this._maxListeners){
throw new RangeError("The maximum number of listeners is 10.")}}else{
this._events[type]=[listener];
this._eventsCount++; }}// One more option
EventEmitter.prototype.addListener=function(type,listener,options={once:false}){
if(options.once){
this.on(type,listener);
}
else{
this.once(type,listener); }}//once, add once, remove
EventEmitter.prototype.once=function(type,listener){
var me=this;
// Return parameters
function oneTime(. args){
// Change this, this always points to the EventEmitter objectlistener.call(me,... args); me.off(type,oneTime); } me.on(type,oneTime); }//remove Listener
EventEmitter.prototype.removeListener=function(type,listener){
if(this._events[type]){
var index=this._events[type].indexOf(listener);
// console.log(index)
if(index>=0) {this._events[type].splice(index,1);
}
}
}
EventEmitter.prototype.off=EventEmitter.prototype.removeListener;
// Remove all
EventEmitter.prototype.removeAllListeners=function(type){
if(this._events[type]){
this._events[type]=[]; }}/ / triggers
EventEmitter.prototype.emit=function(type,... args){
if(this._events[type]){
this._events[type].forEach(fn= >fn.call(this. args)) } }module.exports={
EventEmitter
}
Copy the code
That’s it. If you have any questions, please leave them in the comments section and write ES6 grammar later.