YouTip LogoYouTip

Nodejs Event

All asynchronous I/O operations in Node.js send an event to the event queue upon completion. Many objects in Node.js emit events: a `net.Server` object emits an event every time a new connection is made, and an `fs.readStream` object emits an event when a file is opened. All these objects that produce events are instances of `events.EventEmitter`. EventEmitter is the core module in Node.js used for creating, registering, and triggering events. EventEmitter is the foundation of event-driven programming, helping developers easily implement the publish-subscribe mechanism for events. * * * ## The EventEmitter Class The `events` module provides only one object: `events.EventEmitter`. The core of EventEmitter is the encapsulation of event triggering and event listener functionality. You can access this module via `require("events");`. ## Example ```javascript // Import the events module var events = require('events'); // Create an eventEmitter object var eventEmitter = new events.EventEmitter(); If an error occurs during the instantiation of an EventEmitter object, it will trigger an `error` event. When a new listener is added, the `newListener` event is triggered, and when a listener is removed, the `removeListener` event is triggered. Let's illustrate the usage of EventEmitter with a simple example: ## Example ```javascript //event.js file var EventEmitter = require('events').EventEmitter; var event = new EventEmitter(); event.on('some_event', function(){ console.log('some_event event triggered'); }); setTimeout(function(){ event.emit('some_event'); }, 1000); Running this code, after 1 second, the console outputs **some_event event triggered**. The principle is that the `event` object registered a listener for the `some_event` event, and then we used `setTimeout` to send the `some_event` event to the `event` object after 1000 milliseconds, which calls the listener for `some_event`. The execution result is as follows: $ node event.js some_event event triggered Each event of an EventEmitter consists of an event name and several parameters. The event name is a string, usually conveying a certain meaning. For each event, EventEmitter supports multiple event listeners. When an event is triggered, the event listeners registered for that event are called sequentially, and the event parameters are passed as arguments to the callback function. Let's explain this process with the following example: ## Example ```javascript //event.js file var events = require('events'); var emitter = new events.EventEmitter(); emitter.on('someEvent', function(arg1, arg2){ console.log('listener1', arg1, arg2); }); emitter.on('someEvent', function(arg1, arg2){ console.log('listener2', arg1, arg2); }); emitter.emit('someEvent', 'arg1 parameter', 'arg2 parameter'); Executing the above code, the result is as follows: $ node event.js listener1 arg1 parameter arg2 parameter listener2 arg1 parameter arg2 parameter In the above example, `emitter` registered two event listeners for the `someEvent` event, and then triggered the `someEvent` event. The execution result shows that the two event listener callback functions were called one after another. This is the simplest usage of EventEmitter. EventEmitter provides multiple properties, such as **on** and **emit**. The **on** function is used to bind an event function, and the **emit** property is used to trigger an event. Next, let's take a closer look at the properties of EventEmitter. ### Methods | No. | Method & Description | | --- | --- | | 1 | **addListener(event, listener)** Adds a listener to the end of the listeners array for the specified event. | | 2 | **on(event, listener)** Registers a listener for the specified event, accepting a string `event` and a callback function. `server.on('connection', function (stream) { console.log('someone connected!');});` | | 3 | **once(event, listener)** Registers a one-time listener for the specified event, meaning the listener will be triggered at most once and is removed immediately after triggering. `server.once('connection', function (stream) { console.log('Ah, we have our first user!');});` | | 4 | **removeListener(event, listener)** Removes a listener for the specified event. The listener must be a listener that has been registered for that event. It accepts two parameters: the first is the event name, and the second is the callback function name. `var callback = function(stream) { console.log('someone connected!');}; server.on('connection', callback); // ... server.removeListener('connection', callback);` | | 5 | **removeAllListeners()** Removes all listeners for all events. If an event is specified, it removes all listeners for that specified event. | | 6 | **setMaxListeners(n)** By default, EventEmitters will output a warning if you add more than 10 listeners. The `setMaxListeners` function is used to change the default limit on the number of listeners. | | 7 | **listeners(event)** Returns the array of listeners for the specified event. | | 8 | **emit(event, , , [...])** Executes each listener in the order they were registered. Returns `true` if the event has registered listeners, otherwise returns `false`. | ### Class Methods | No. | Method & Description | | --- | --- | | 1 | **listenerCount(emitter, event)** Returns the number of listeners for the specified event. `events.EventEmitter.listenerCount(emitter, eventName)` // Deprecated, not recommended `emitter.listenerCount(eventName)` // Recommended | Register an event listener: ## Example ```javascript const EventEmitter = require('events'); const myEmitter = new EventEmitter(); // Register an event listener myEmitter.on('sayHello', (name) => { console.log(`Hello, ${name}!`); }); // Trigger the event myEmitter.emit('sayHello', 'Alice'); Output: Hello, Alice! Register a one-time event using `once()`: ```javascript myEmitter.once('init', () => { console.log('Initialization event occurred'); }); myEmitter.emit('init'); // Prints: Initialization event occurred myEmitter.emit('init'); // Will not trigger again Parameters can be passed when triggering an event for the listeners to use: ## Example ```javascript myEmitter.on('data', (value1, value2) => { console.log(`Received values: ${value1}, ${value2}`); }); myEmitter.emit('data', 'Node.js', 'EventEmitter'); // Output: Received values: Node.js, EventEmitter If a triggered event has no corresponding listener, EventEmitter will throw an error: ## Example ```javascript myEmitter.on('error', (err) => { console.error('Error event triggered:', err); }); myEmitter.emit('error', new Error('Something went wrong')); // Prints: Error event triggered: Error: Something went wrong ### Events | No. | Event & Description | | --- | --- | | 1 | **newListener** * **event** - String, the event name * **listener** - The event handler function This event is triggered when a new listener is added. | | 2 | **removeListener** * **event** - String, the event name * **listener** - The event handler function Removes a listener from the specified listener array. Note that this operation will change the index of listeners after the removed listener. | ### Example The following example demonstrates the application of the EventEmitter class through the `connection` (connection) event. Create the `main.js` file with the following code: ## Example ```javascript var events = require('events'); var eventEmitter = new events.EventEmitter(); // Listener #1 var listener1 = function listener1() { console.log('Listener listener1 executed.'); } // Listener #2 var listener2 = function listener2() { console.log('Listener listener2 executed.'); } // Bind the connection event, with listener1 as the handler eventEmitter.addListener('connection', listener1); // Bind the connection event, with listener2 as the handler eventEmitter.on('connection', listener2); var eventListeners = eventEmitter.listenerCount('connection'); console.log(eventListeners + " listeners are listening to the connection event."); // Handle the connection event eventEmitter.emit('connection'); // Remove the bound listener1 function eventEmitter.removeListener('connection', listener1); console.log("listener1 is no longer listening."); // Trigger the connection event eventEmitter.emit('connection'); eventListeners = eventEmitter.listenerCount('connection'); console.log(eventListeners + " listeners are listening to the connection event."); console.log("Program execution completed."); The execution result of the above code is as follows: $ node main.js 2 listeners are listening to the connection event. Listener listener1 executed. Listener listener2 executed. listener1 is no longer listening. Listener listener2 executed. 1 listener is listening to the connection event. Program execution completed. * * * ## The error Event EventEmitter defines a special event `error`, which carries the semantics of an error. We usually trigger the `error` event when encountering an exception. When `error` is triggered, EventEmitter stipulates that if there are no corresponding listeners, Node.js will treat it as an exception, exit the program, and output an error message. We generally need to set listeners for objects that may trigger the `error` event to avoid the entire program crashing when an error is encountered. For example: ```javascript var events = require('events'); var emitter = new events.EventEmitter(); emitter.emit('error'); Running this will display the following error: node.js:201 throw e; // process.nextTick error, or 'error' event on first tick ^ Error: Uncaught, unspecified 'error' event. at EventEmitter.emit (events.js:50:15) at Object. (/home/byvoid/error.js:5:9) at Module._compile (module.js:441:26) at Object..js (module.js:459:10) at Module.load (module.js:348:31) at Function._load (module.js:308:12) at Array.0 (module.js:479:10) at EventEmitter._tickCallback (node.js:192:40) * * * ## Inheriting EventEmitter Most of the time, we don't use EventEmitter directly, but inherit it in objects. Core modules that support event response, including `fs`, `net`, and `http`, are all subclasses of EventEmitter. Why do we do this? There are two reasons: * First, it is semantically appropriate for objects with specific functionalities to implement events. The listening and occurrence of events should be methods of an object. * Second, JavaScript's object mechanism is prototype-based and supports partial multiple inheritance. Inheriting EventEmitter does not disrupt the original inheritance relationship of the object. Most Node.js core modules (such as HTTP, file system) inherit from EventEmitter. You can create your own classes to inherit from EventEmitter. ## Example ```javascript class MyEmitter extends EventEmitter {} const customEmitter = new MyEmitter(); customEmitter.on('customEvent', () => { console.log('Custom event fired'); }); customEmitter.emit('customEvent');
← Nodejs FunctionCsharp Tutorial β†’