Node. The events module of JS provides an external EventEmitter object for Node. Events in JS are managed uniformly. Because Node.js uses event-driven mechanisms, and EventEmitter is Node.js implements the foundation of event driven. On the basis of EventEmitter, Node. Almost all modules in JS inherit this class to implement an asynchronous event-driven architecture.
Example
var events = require('events'); var eventEmitter = new events.EventEmitter(); eventEmitter.on('say',function(name){ console.log('Hello',name); }) eventEmitter.emit('say','Jack');
API for EventEmitter Module
Comparison of addListener and removeListener, on and off methods
The addListener method adds a listener for a specified event, which is essentially the same function as the on method, which is actually an alias for the addListener method. Both are implemented in the same way, while the removeListener method is used to remove the listener for an event, and off is also an alias for removeListener.
var events = require("events") const { emit } = require("process") var emitter = new events.EventEmitter() function hello1(name) { console.log(" 1", name) } function hello2(name) { console.log("2", name) } emitter.addListener("say", hello1) emitter.addListener("say", hello2) emitter.emit("say", "jake") // 1 jake // 2 jake emitter.removeListener("say",hello1) emitter.emit("say","jake") // 2 jake
removeListener and removeAllListeners
The removeListener method refers to removing one listener for a specified event, while removeAllListeners refers to removing all listeners for a specified event.
emitter.removeAllListeners('say'); emitter.emit('say','John'); //removeAllListeners removes all listening on the say event //So there is no output
on and once method differences
The difference between on and once is that on's method continuously listens for events to which a listener is added for a given event. The once method adds listeners, which are eliminated after listening once.
emitter.once('see',hello); emitter.emit('see','Tom'); //hello Tom will only be output once
Implement an EventEmitter
function EventEmitter() { this.__events = {} } EventEmitter.VERSION = '1.0.0'; EventEmitter.prototype.on = function (eventName, listener) { if (!eventName || !listener) return; // Determine whether the callback listener is a function if (!isValidListener(listener)) { throw new TypeError('listener must be a function'); } var events = this.__events; var listeners = events[eventName] = events[eventName] || []; var listenerIsWrapped = typeof listener === 'object'; // Do not add events repeatedly to determine if they are the same if (indexOf(listeners, listener) === -1) { listeners.push(listenerIsWrapped ? listener : { listener: listener, once: false }); } return this; }; // Determine if it is a legitimate listener function isValidListener(listener) { if (typeof listener === 'function') { return true; } else if (listener && typeof listener === 'object') { return isValidListener(listener.listener); } else { return false; } } // As the name implies, determine if a new custom event exists function indexOf(array, item) { var result = -1 item = typeof item === 'object' ? item.listener : item; for (var i = 0, len = array.length; i < len; i++) { if (array[i].listener === item) { result = i; break; } } return result; }
The core idea of the on method is that when a call subscribes to a custom event, push the custom event to this. u once it is valid through validation Evets is stored in this object, so when you need to start, you can get u directly from The listener callback function for the corresponding event in events, which can then be executed directly to achieve the desired effect.
emit,off
EventEmitter.prototype.emit = function(eventName, args) { // Get callback functions for corresponding custom events directly from internal objects var listeners = this.__events[eventName]; if (!listeners) return; // Multiple listener s need to be considered for (var i = 0; i < listeners.length; i++) { var listener = listeners[i]; if (listener) { listener.listener.apply(this, args || []); // Special handling of true once in listener if (listener.once) { // No more executions after one execution this.off(eventName, listener.listener) } } } return this; }; EventEmitter.prototype.off = function(eventName, listener) { var listeners = this.__events[eventName]; if (!listeners) return; var index; for (var i = 0, len = listeners.length; i < len; i++) { if (listeners[i] && listeners[i].listener === listener) { index = i; break; } } // Key to off, remove binding events from listeners array if (typeof index !== 'undefined') { listeners.splice(index, 1, null) } return this; };
Emi is actually handled by apply executing the corresponding custom event. In the process of execution, the custom event bound by the once method is specially handled. When the once is true, the off method is triggered to unbind the custom event, so as to achieve the effect of one execution of the custom event.
once,alloff
EventEmitter.prototype.once = function(eventName, listener){ // Direct call to on method, once parameter passed in true, once processing after execution return this.on(eventName, { listener: listener, once: true }) }; EventEmitter.prototype.allOff = function(eventName) { // If the eventName exists, empty its corresponding listeners array directly if (eventName && this.__events[eventName]) { this.__events[eventName] = [] } else { this.__events = {} } };
The once method is essentially a call to the on method, except that the parameters passed in distinguish between one execution and another. When the emit method is triggered again, the once binding is executed once before it is unbound.
The alloff method is also well understood, that is, the internal u The events object is emptied, after which the callback function cannot be triggered if the custom event is triggered again.