Maison >interface Web >js tutoriel >Comment créer un émetteur d'événements prioritaires personnalisé dans Node.js
npm i -d @types/node tsx typescript npx tsc --init
// tsconfig.json { "compilerOptions": { "target": "es2016", "module": "ES6", "moduleResolution": "nodenext", "allowImportingTsExtensions": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, "skipLibCheck": true, "sourceMap": true, "outDir": "./dist", "types": ["node"] }, "include": ["src/**/*.ts"], "exclude": ["node_modules"] } // package.json { "name": "node-starter", "version": "0.0.0", "type": "module", // This should be set to "module" for using ES6 modules "scripts": { "test": "jest" }, "devDependencies": { "@types/jest": "^29.5.14", "jest": "^29.7.0", "typescript": "^5.7.2" }, "dependencies": { "@types/node": "^22.10.2", "tsx": "^4.19.2" } }
Node.js utilise EventEmitter comme classe fondamentale pour gérer les événements dans la programmation asynchrone. Cette classe vous permet d'enregistrer des auditeurs pour des événements spécifiques et d'émettre ces événements en cas de besoin. Par défaut, EventEmitter traite les événements dans l'ordre dans lequel les écouteurs ont été ajoutés. Cependant, nous pouvons parfois souhaiter donner la priorité à l’exécution de certains auditeurs par rapport à d’autres. C'est là que nous pouvons introduire un système d'événements basé sur les priorités.
Héritage de EventEmitter :
Pour créer un émetteur d'événements personnalisé avec gestion des priorités, nous devons étendre la classe EventEmitter intégrée. Cela nous donne accès à toutes les méthodes intégrées comme on, émettre et supprimerListener.
import EventEmitter from 'events'; export class PriorityEmitter extends EventEmitter { private _listeners: Record< string, { listener: (...args: any[]) => void; priority: number }[] >; constructor() { super(); this._listeners = {}; } }
- `PriorityEmitter` extends `EventEmitter`, so it inherits all of its functionality. - We introduce a new internal property `_listeners` to store listeners along with their priorities.
Remplacement de la méthode on :
En remplaçant la méthode on, nous pouvons ajouter une logique personnalisée pour stocker les auditeurs avec leurs priorités et les trier en fonction de leur priorité.
on(event: string, listener: (...args: any[]) => void, priority = 0) { if (!this._listeners[event]) this._listeners[event] = []; this._listeners[event].push({ listener, priority }); this._listeners[event].sort((a, b) => b.priority - a.priority); return this; }
- For production usage, consider using other data structures instead of arrays, which maintain order. - When a listener is added using `on`, we push the listener and its priority into the `_listeners` array. - We then sort the listeners in descending order based on the priority. This ensures that higher-priority listeners are executed first. - The default priority is `0` if not specified.
Remplacer la méthode d'émission :
La méthode submit déclenche l'événement et exécute les écouteurs. Dans la méthode remplacée, nous traitons d'abord les auditeurs de _listeners en fonction de leur priorité.
emit(event: string, ...args: any[]) { if (this._listeners[event]) { for (const { listener } of this._listeners[event]) { listener(...args); } } return super.emit(event, ...args); }
- For the given event, we iterate over the sorted listeners and call each listener. - After handling the custom priority-based logic, we call the parent class’s `emit` method to ensure the standard behavior is also preserved.
Remplacement de la méthode removeListener :
La méthode removeListener est remplacée pour garantir que les écouteurs sont correctement supprimés en fonction de leur référence. Puisque nous stockons les auditeurs avec leurs priorités, nous filtrons le bon auditeur.
removeListener(event: string, listener: (...args: any[]) => void) { if (this._listeners[event]) { this._listeners[event] = this._listeners[event].filter( (stored_listener) => stored_listener.listener !== listener ); } super.removeListener(event, listener); return this; }
- We filter the listener array to remove the listener with the exact reference. - Then we call `super.removeListener` to ensure proper cleanup and avoid memory leaks.
Voici un exemple pour démontrer comment fonctionne le PriorityEmitter dans la pratique :
const pe = new PriorityEmitter(); // Listener with higher priority pe.on('greet', (name: string) => { console.log(`Hello ${name}!`); }, 2); // Listener with lower priority pe.on('greet', (name: string) => { console.log(`Hi, ${name}!`); }, 1); // Emitting the event pe.emit('greet', 'Alice');
Sortie :
npm i -d @types/node tsx typescript npx tsc --init
// tsconfig.json { "compilerOptions": { "target": "es2016", "module": "ES6", "moduleResolution": "nodenext", "allowImportingTsExtensions": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, "skipLibCheck": true, "sourceMap": true, "outDir": "./dist", "types": ["node"] }, "include": ["src/**/*.ts"], "exclude": ["node_modules"] } // package.json { "name": "node-starter", "version": "0.0.0", "type": "module", // This should be set to "module" for using ES6 modules "scripts": { "test": "jest" }, "devDependencies": { "@types/jest": "^29.5.14", "jest": "^29.7.0", "typescript": "^5.7.2" }, "dependencies": { "@types/node": "^22.10.2", "tsx": "^4.19.2" } }
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!