Node.js 이벤트 이미터


Node.js의 모든 비동기 I/O 작업은 완료되면 이벤트 대기열로 이벤트를 보냅니다.

Node.js의 많은 객체는 이벤트를 생성합니다. net.Server 객체는 새로운 연결이 있을 때마다 이벤트를 생성하고, fs.readStream 객체는 파일이 열릴 때 이벤트를 생성합니다. 이러한 이벤트 생성 객체는 모두 events.EventEmitter의 인스턴스입니다.


EventEmitter 클래스

events 모듈은 events.EventEmitter라는 하나의 개체만 제공합니다. EventEmitter의 핵심은 이벤트 트리거링과 이벤트 리스너 기능을 캡슐화하는 것입니다.

require("events");를 통해 이 모듈에 액세스할 수 있습니다.

// 引入 events 模块
var events = require('events');
// 创建 eventEmitter 对象
var eventEmitter = new events.EventEmitter();

EventEmitter 객체는 인스턴스화 중에 오류가 발생하면 'error' 이벤트를 트리거합니다. 새 리스너가 추가되면 'newListener' 이벤트가 시작되고, 리스너가 제거되면 'removeListener' 이벤트가 시작됩니다.

아래에서는 EventEmitter의 사용법을 설명하기 위해 간단한 예를 사용합니다.

//event.js 文件
var EventEmitter = require('events').EventEmitter; 
var event = new EventEmitter(); 
event.on('some_event', function() { 
	console.log('some_event 事件触发'); 
}); 
setTimeout(function() { 
	event.emit('some_event'); 
}, 1000);

실행 결과는 다음과 같습니다.

이 코드를 실행하고 1초 후에 콘솔 출력 'some_event 이벤트가 트리거됨'. 원칙은 이벤트 객체가 some_event 이벤트에 대한 리스너를 등록한 다음 setTimeout을 사용하여 1000밀리초 후에 이벤트 객체에 some_event 이벤트를 보내는 것입니다. 이때 some_event에 대한 리스너가 호출됩니다.

$ node event.js 
some_event 事件触发

EventEmitter의 각 이벤트는 이벤트 이름과 여러 매개변수로 구성됩니다. 이벤트 이름은 일반적으로 특정 의미를 표현하는 문자열입니다. 각 이벤트에 대해 EventEmitter는 여러 이벤트 리스너를 지원합니다.

이벤트가 발생하면 해당 이벤트에 등록된 이벤트 리스너가 순차적으로 호출되고, 이벤트 매개변수가 콜백 함수 매개변수로 전달됩니다.

다음 예를 들어 이 프로세스를 설명하겠습니다.

//event.js 文件
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 参数', 'arg2 参数');

위 코드를 실행하면 실행 결과는 다음과 같습니다.

$ node event.js 
listener1 arg1 参数 arg2 参数
listener2 arg1 参数 arg2 参数

위 예에서 이미터는 someEvent 이벤트에 대해 두 개의 이벤트 리스너를 등록한 후 트리거되었습니다. someEvent 이벤트.

실행 결과에서 두 개의 이벤트 리스너 콜백 함수가 연속적으로 호출되는 것을 볼 수 있습니다. 이것은 EventEmitter의 가장 간단한 사용법입니다.

EventEmitter는 onemit과 같은 여러 속성을 제공합니다. on 함수는 이벤트 함수를 바인딩하는 데 사용되고 emit 속성은 이벤트를 트리거하는 데 사용됩니다. 다음으로 EventEmitter의 속성을 자세히 살펴보겠습니다.

Method

Serial numberMethod & Description
1addListener(event,listener)
특정 이벤트에 대한 리스너를 리스너 배열 끝에 추가합니다.
2on(event, listening)
문자열 이벤트와 콜백 함수를 받아 지정된 이벤트에 대한 리스너를 등록합니다.
server.on('connection', function (stream) {
  console.log('someone connected!');
});
3once(이벤트, 리스너)
지정된 이벤트에 대한 일회성 리스너를 등록합니다. 즉, 리스너는 최대 한 번만 트리거되고 리스너는 트리거된 후 즉시 해제됩니다.
server.once('connection', function (stream) {
  console.log('Ah, we have our first user!');
});
4removeListener(event, Listener)
지정된 이벤트에 대한 리스너를 제거합니다. 리스너는 해당 이벤트에 등록된 리스너여야 합니다.
var callback = function(stream) {
  console.log('someone connected!');
};
server.on('connection', callback);
// ...
server.removeListener('connection', callback);
5removeAllListeners([event])
이벤트가 지정된 경우 지정된 이벤트에 대한 모든 리스너를 제거합니다.
6setMaxListeners(n)
기본적으로 EventEmitters는 리스너를 10개 이상 추가하면 경고 메시지를 출력합니다. setMaxListeners 함수는 리스너 수의 기본 제한을 늘리는 데 사용됩니다.
7listeners(event)
지정된 이벤트에 대한 리스너 배열을 반환합니다.
8emit(event, [arg1], [arg2], [...])
각 리스너를 매개변수 순서대로 실행합니다. 이벤트에 등록된 리스너가 있으면 true를 반환합니다. 그것은 거짓을 반환합니다.

클래스 메서드

일련 번호메서드 및 설명
1listenerCount(emitter, event)
지정된 이벤트에 대한 리스너 수를 반환합니다. 이벤트 이름

listener

- 이벤트 처리 기능 2

Example

다음 예제에서는 연결 이벤트를 통해 EventEmitter 클래스를 적용하는 방법을 보여줍니다.

main.js 파일을 생성합니다. 코드는 다음과 같습니다.

var events = require('events');
var eventEmitter = new events.EventEmitter();

// 监听器 #1
var listener1 = function listener1() {
   console.log('监听器 listener1 执行。');
}

// 监听器 #2
var listener2 = function listener2() {
  console.log('监听器 listener2 执行。');
}

// 绑定 connection 事件,处理函数为 listener1 
eventEmitter.addListener('connection', listener1);

// 绑定 connection 事件,处理函数为 listener2
eventEmitter.on('connection', listener2);

var eventListeners = require('events').EventEmitter.listenerCount(eventEmitter,'connection');
console.log(eventListeners + " 个监听器监听连接事件。");

// 处理 connection 事件 
eventEmitter.emit('connection');

// 移除监绑定的 listener1 函数
eventEmitter.removeListener('connection', listener1);
console.log("listener1 不再受监听。");

// 触发连接事件
eventEmitter.emit('connection');

eventListeners = require('events').EventEmitter.listenerCount(eventEmitter,'connection');
console.log(eventListeners + " 个监听器监听连接事件。");

console.log("程序执行完毕。");

위 코드의 실행 결과는 다음과 같습니다.

$ node main.js
2 个监听器监听连接事件。
监听器 listener1 执行。
监听器 listener2 执行。
listener1 不再受监听。
监听器 listener2 执行。
1 个监听器监听连接事件。
程序执行完毕。

error event

EventEmitter는 이벤트의 의미를 포함하는 특수 이벤트 오류를 ​​정의합니다. 오류가 발생하면 도착합니다. 오류 이벤트는 일반적으로 예외가 발생할 때 트리거됩니다.

오류가 발생하면 EventEmitter는 응답이 없으면 다음을 규정합니다. 해당 리스너를 사용하면 Node.js는 이를 예외로 처리하고 프로그램을 종료한 후 오류 메시지를 출력합니다.

우리는 일반적으로 오류 발생에 대해 걱정해야 합니다. 오류가 발생했을 때 전체 프로그램이 충돌하는 것을 방지하려면 이벤트 개체에 리스너를 설정하세요. 예:

var events = require('events'); 
var emitter = new events.EventEmitter(); 
emitter.emit('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.<anonymous> (/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

대부분의 경우 EventEmitter를 직접 사용하지 않고 객체에서 상속합니다. fs, net을 포함하여 이벤트 응답을 지원하는 핵심 모듈이 EventEmitter의 하위 클래스인 경우 http를 포함합니다.

왜 이러는 걸까요? 두 가지 이유가 있습니다:

우선, 특정 엔터티 기능을 가진 객체의 이벤트 구현은 의미론을 따릅니다. 이벤트 수신 및 방출은 객체의 메서드여야 합니다.

둘째, JavaScript의 객체 메커니즘은 프로토타입을 기반으로 하며 이를 지원합니다. 부분 다중 상속, EventEmitter 상속은 객체의 원래 상속 관계를 방해하지 않습니다.

이 이벤트는 새 리스너가 추가되면 트리거됩니다.
removeListener
  • event - 문자열, 이벤트 이름

  • listener - 이벤트 함수 처리

지정된 리스너 배열에서 리스너를 제거합니다. 이 작업은 삭제된 리스너 이후 해당 리스너의 인덱스를 변경한다는 점에 유의하세요.