> 웹 프론트엔드 > JS 튜토리얼 > Node.js에서 사용자 정의 우선순위 이벤트 이미터를 만드는 방법

Node.js에서 사용자 정의 우선순위 이벤트 이미터를 만드는 방법

Susan Sarandon
풀어 주다: 2024-12-20 16:05:11
원래의
1028명이 탐색했습니다.

How to Create a Custom Priority Event Emitter in Node.js

설정:

라이브러리 설치 및 설정

npm i -d @types/node tsx typescript
npx tsc --init
로그인 후 복사
로그인 후 복사

tsconfig.json 및 package.json 변경

// 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 이해

Node.js는 비동기 프로그래밍에서 이벤트를 처리하기 위한 기본 클래스로 EventEmitter를 사용합니다. 이 클래스를 사용하면 특정 이벤트에 대한 리스너를 등록하고 필요할 때 해당 이벤트를 내보낼 수 있습니다. 기본적으로 EventEmitter는 리스너가 추가된 순서대로 이벤트를 처리합니다. 그러나 때로는 특정 리스너의 실행을 다른 리스너보다 우선순위에 두기를 원할 수도 있습니다. 여기서 우선순위 기반 이벤트 시스템을 도입할 수 있습니다.

우선순위 EventEmitter를 생성하는 단계

  1. 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.
로그인 후 복사
  1. 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.
로그인 후 복사
  1. 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.
로그인 후 복사
  1. 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의 작동 방식

  • 이벤트가 발생하면 우선순위에 따라 리스너가 호출됩니다. 우선순위가 높을수록 더 일찍 실행됩니다.
  • 동일한 우선순위를 가진 리스너는 추가된 순서대로 실행됩니다.

사용예

다음은 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
로그인 후 복사
로그인 후 복사
  • 우선순위가 2인 리스너(Hello Alice!)가 먼저 호출됩니다.
  • 다음으로 우선 순위가 1인 청취자(Hi, Alice!)가 호출됩니다.

성능 고려 사항

  • 데이터 구조 선택: 이 기본 예에서는 배열을 사용하여 리스너를 저장하고 리스너가 추가될 때마다 정렬합니다. 이는 청취자가 많을 때 비효율적일 수 있습니다. 성능이 중요한 환경에서 우선순위를 처리하기 위한 더 나은 솔루션은 효율적인 삽입 및 제거 작업을 허용하는 최대 힙을 사용하는 것입니다.
  • 프로덕션에서 사용: 프로덕션 수준 애플리케이션의 경우 우선순위 대기열을 제공하는 고급 데이터 구조나 외부 라이브러리를 사용하여 많은 수의 이벤트를 보다 효율적으로 처리하는 것이 좋습니다.

완전한 코드

// 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿