Множество функционала Node.js применяет асинхронную событийную архитектуру, где различные действия выполняются в ответ на возникшие события. В подобной архитектуре сначала специальные объекты, которые называются эмиттерами событий (event emitter), генерируют события. Затем специальные функции - обработчики или слушатели событий обрабатывают возникшее событие.
Итак, для генерации событий нам нажем эмиттер событий. Эмиттер событий представляет объекты типа EventEmitter. Данный тип определен в модуле "events":
const EventEmitter = require("events"); // определяем эмиттер событий const emitter = new EventEmitter();
EventEmitter предоставляет ряд методов для управления обработчиками событий:
on (eventName, listener)
: псевдоним метода on(). Регистрирует новый слушатель listener для события eventName.
addListener(eventName, listener)
: псевдоним метода on(). Регистрирует новый слушатель listener сдля события eventName.
emit(eventName [, args])
: запускает событие. В качестве обязательного параметра принимает имя события. Также дополнительно можно передать необязательный параметр - аргументы для обработчика события
eventNames()
: возвращает массив с именами событий, для которых зарегистрированы слушатели
getMaxListeners()
: возвращает максимальное количество слушателей для данного эмиттера событий.
listenerCount(eventName)
: возвращает количество слушателей события eventName
listeners(eventName)
: возвращает массив со слушателями события eventName.
once(eventName, listener)
: регистрирует новый слушатель listener для события eventName, но выполняет его не более одного раза.
prependListener(eventName, listener)
: регистрирует новый слушатель listener для события eventName и помещает его в начало массива
слушателей события eventName.
prependOnceListener(eventName, listener)
: аналогичен prependListener() за тем исключением, что слушатель listener
вызывается не более одного раза.
removeAllListeners([eventName])
: удаляет всех слушателей события eventName
removeListener(eventName, listener)
: удаляет слушателя listener для события eventName.
setMaxListeners (п)
: устанавливает максимальное количество слушателей событий, которые можно зарегистрировать для каждого события
в эмиттере событий
Итак, для генерации события у EventEmitter
надо вызвать метод emit(), в который передается имя события.
Такб определим в файле app.js следующий код:
const EventEmitter = require("events"); // определяем эмиттер событий const emitter = new EventEmitter(); // имя события, которое будет обрабатываться const eventName = "greet"; // генерируем событие greet emitter.emit(eventName);
Здесь генерируется событие "greet". Названия событий произвольные.
Однако в ответ на это событие ничего не произойдет, событие пока никак не обрабатывается. Для регистрации обработчика события применяется метод on(), в который передается имя события и функция обработчика. Обработаем событие "greet":
const EventEmitter = require("events"); // определяем эмиттер событий const emitter = new EventEmitter(); // имя события, которое будет обрабатываться const eventName = "greet"; // регистрируем обработчик для события "greet" emitter.on(eventName, function(){ console.log("Hello World!"); }); // генерируем событие greet emitter.emit(eventName);
Здесь в качестве обработчика применяется функция, которая выводит строку "Hello World!" на консоль.
Запустим приложение:
c:\app> node app.js Hello World! c:\app>
Можно установить несколько обработчиков на одно событие:
const EventEmitter = require("events"); // определяем эмиттер событий const emitter = new EventEmitter(); // имя события, которое будет обрабатываться const eventName = "greet"; // регистрируем три обработчика для события "greet" emitter.on(eventName, function(){ console.log("Hello World!"); }); emitter.on(eventName, function(){ console.log("Привет мир!"); }); emitter.on(eventName, function(){ console.log("Hallo Welt!"); }); // генерируем событие greet emitter.emit(eventName);
В итоге при генерации события будут выполняться сразу три обработчика:
c:\app> node app.js Hello World! Привет мир! Hallo Welt! c:\app>
При вызове события в качестве второго параметра в метод emit() можно передавать некоторый объект, который передается в функцию обработчика события:
const EventEmitter = require("events"); const emitter = new EventEmitter(); const eventName = "greet"; emitter.on(eventName, function(data){ console.log(data); }); emitter.emit(eventName, "Привет пир!");
В приложении мы можем оперировать сложными объектами, для которых также можно определять события, но для этого их надо связать с объектом EventEmitter. Например:
const EventEmitter = require("events"); const eventName = "greet"; emitter.on(eventName, function(data){ console.log(data); }); class User extends EventEmitter { constructor(username){ super(); // вызываем конструктор EventEmitter this.name = username; } sayHi() { console.log("Привет. Меня зовут", this.name); this.emit(eventName, this.name); // генерируем событие, передаем обработчику имя } } const tom = new User("Tom"); // добавляем к объекту tom обработку события "greet" // обработчик ожидает получить через параметр имя пользователя tom.on(eventName, function(username){ console.log("Привет,", username); }); // при выполнении метода генерируется событие "greet" tom.sayHi();
Здесь определен класс User, который наследуется от типа EventEmitter. Через конструктор класс User получает имя пользователя. В классе User определен метод sayHi, в котором генерируется событие "greet", а обработчику событий передается имя пользователя.
Поскольку User унаследован от EventEmitter, то объекты User также имеют метод on()
, через который можно установить
обработчик события. Этот обработчик будет вызван при выполнении метода sayHi()
.
Пример работы программы:
c:\app> node app.js Привет. Меня зовут Tom Привет, Tom c:\app>
В качестве альтернативы наследованию можно передавать в объект объект EventEmitter:
const EventEmitter = require("events"); const emitter = new EventEmitter(); const eventName = "greet"; emitter.on(eventName, function(username){ console.log("Прив", username); }); class User{ constructor(username, emitter){ this.name = username; this.emitter = emitter; } sayHi() { console.log("Привет. Меня зовут", this.name); this.emitter.emit(eventName, this.name); // генерируем событие, передаем обработчику имя } } const tom = new User("Tom", emitter); tom.sayHi();