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 使用 EventEmitter 作為非同步程式設計中處理事件的基礎類別。此類別可讓您註冊特定事件的偵聽器並在需要時發出這些事件。預設情況下,EventEmitter 會依照新增偵聽器的順序處理事件。然而,有時我們可能希望優先執行某些偵聽器而不是其他偵聽器。這就是我們可以引入基於優先順序的事件系統的地方。
繼承自EventEmitter:
要建立具有優先權處理功能的自訂事件發射器,我們需要擴展內建的 EventEmitter 類別。這使我們能夠存取所有內建方法,例如 on、emit 和 removeListener。
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.
重寫 on 方法:
透過重寫 on 方法,我們可以新增自訂邏輯來儲存偵聽器及其優先權,並根據其優先權對它們進行排序。
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.
重寫發射方法:
emit 方法觸發事件並執行偵聽器。在重寫的方法中,我們首先根據優先權處理 _listeners 中的偵聽器。
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.
重寫removeListener方法:
重寫removeListener方法以確保根據引用正確刪除偵聽器。由於我們儲存偵聽器及其優先權,因此我們過濾掉了正確的偵聽器。
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.
這是一個示範 PriorityEmitter 在實務上如何運作的範例:
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');
輸出:
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 中建立自訂優先權事件發射器的詳細內容。更多資訊請關注PHP中文網其他相關文章!