To quote the official note: Most of node.js’ core apis are built around the idiomatic asynchronous event-driven architecture, in which certain types of objects (called “triggers”) fire named events that cause Function objects (” listeners “) to be called.
Through the study and application of NodeJS, we know that NodeJS adopts single-thread, event-driven, non-blocking I/O architecture design, which is very suitable for high concurrency, I/O intensive applications.
1. What is event-driven?
Event-driven is simply an effective way to listen for changes in the state of an event and act accordingly when such changes occur.
Take an application scenario to understand life: when we went to a restaurant order, when we place the order, the waiter told us that the order number (this can be understood as a registered for an event), we sat in the waiting, this time has been monitored the waiter shout our ears, when shouted to us, we can go to the front desk for dinner.
2. Event model
NodeJS ‘event architecture follows the classic subscription-to-publish model
Subscription and publication mode, also known as message mechanism, defines a dependency relationship, which can be understood as 1 pair of N(multiple or single) observers simultaneously monitor the corresponding state change of an object, and once the change is notified to all observers, thus triggering the corresponding events registered by observers. This design pattern addresses the functional coupling between the subject object and the observer.
3. The events module
Events module is a very important module of NodeJS. Most modules in Node inherit events class, such as FS, HTTP, NET and so on. EventEmitter provides an object events.EventEmitter, whose core is EventEmitter and event listener.
Simple use:
import { EventEmitter } from 'events';
class MyEmiter extends EventEmitter{};
const myEmitter = new MyEmiter();
myEmitter.on('hello'.() = > {
console.log('Hello, someone called you.');
});
myEmitter.emit('hello');
Copy the code
4. Core API of Events module
4.1 eventEmitter.on(eventName, callback)
Register listening events
Parameters:
- EventName: indicates the eventName
- Callback: The event triggers the callback function to be called
4.2 eventEmitter.once(eventName, callback)
You can register a listener that is invoked at most once for a particular event. Once the event is triggered, the listener is deregistered and invoked.
Parameters:
- EventName: indicates the eventName
- Callback: The event triggers the callback function to be called
4.3 eventEmitter.emit(eventName[, ...args])
Triggers the specified listening event
Parameters:
- EventName: indicates the eventName
- Args Optional arguments that are passed to the callback function in sequence;
4.4 eventEmitter.removeListener(eventName, callback)
Removes the listener for the specified event. Note that the listener must be registered. Otherwise invalid.
Parameters:
- EventName: indicates the eventName
- Callback: callback function
4.5 EventEmitter.removeAllListeners(eventName)
Remove all listeners. An event can have multiple listeners. Use this method when you need to remove all listeners.
Parameters:
- EventName: Indicates the name of the event to be removed.
Note that if no parameter is passed, all listening events will be removed. Therefore, it is recommended to use it with caution.
4.6 EventEmitter.listeners(eventName)
Returns a copy of the array of listener binding callback functions for the event named eventName.
4.7 EventEmitter.eventNames()
Returns an array listing the events for which the trigger has registered listeners.
4.8 EventEmitter.setMaxListeners(n)
By default, EventEmitter prints warnings if more than 10 listeners are added for a particular event.
The emitters. SetMaxListeners () method allows you to modify the limitations of this particular EventEmitter instance. The value can be set to Infinity (or 0) to indicate an infinite number of listeners.
5. Asynchrony issues
EventEmitter synchronously calls all listeners in the order in which they were registered. This ensures proper ordering of events and helps avoid race conditions and logic errors.
6. Error handling
When an error occurs in an EventEmitter instance, the typical action is to fire an ‘error’ event. These are considered special cases in Node.js.
If EventEmitter does not register at least one listener for the ‘error’ event, and the ‘error’ event is emitted, it throws an error, prints a stack trace, and exits the Node.js process.
As a best practice, always add listeners for ‘error’ events.
import { EventEmitter } from 'events';
class MyEmiter extends EventEmitter{};
const myEmitter = new MyEmiter();
myEmitter.on('hello'.() = > {
console.log('Hello, someone called you.');
});
myEmitter.on('error'.(e) = > {
console.log(e)
})
myEmitter.emit('hello');
myEmitter.emit('error'.new Error('an error happen'))
Copy the code