Меню

Запускаем и слушаем события в NodeJS

30.06.2018 - Back-end, NodeJS

Events in NodeJS

Один из ключевых принципов nodejs являются — события (events)

Большое количество функционала ядра основано на этом принципе событий.
По простому — событие — это сигнал, что что-то случилось в нашем приложении.
Например, в ноде есть класс http, который мы можем использовать для постройки веб-сервера. Итак, мы прослушиваем указанный порт, и каждый раз когда мы получаем запрос на этот порт, позволим http классу поднять событие. Теперь работа, это ответить на событие, которая в простом случае заключается в чтении запроса, и возврате нужного ответа. Если вы пройдетесь под документации ноды, Вы можете заметить что некоторые классы в ноде, поднимают разные типы событий. И в вашем коды, вы можете быть заинтересованными в ответе на такие события.

Все возможности модуля event можно найти в документации, найдя одноименный модуль. В этом модуле мы можем найти один класс под названием EventEmitter. Это один из ключевых строительных блоков в ноде. Много классов основано на этом EventEmitter. Для начала, давайте загрузим модуль events.

const EventEmitter = require('events');

Обратите внимание, что мы задаем константу с большой буквы, потому что по соглашению наименований — классы задаются с большой буквы.

Класс это контейнер для свойств и функций, которые мы называем — методы. И у нашего EventEmitter есть дофига встроенных методов. Нам в первую очередь нужно создать экземпляр класса.

const emitter = new EventEmitter();

emitter является объектом. У него есть связка методов. В большинстве случаев мы будем использовать только два метода. Один из них emit, который мы будем использовать, чтобы поднять событие. Emit — означает «делать шум», «производить»… Т.е. вы как бы сигналите, что событие произошло. Первый аргумент — это имя события. Позже мы выделим модуль логгера, и каждый раз когда будем логгировать сообщение, мы будем поднимать событие под название messageLogged. Если мы сейчас запустим наше приложение, то ничего не произойдет.

Потому что мы подняли событие, но нигде в нашем приложении нету слушателя, который заинтересован в этом событии. Слушатель (listener) это функция, которая будет вызвана, когда событие поднято.

emitter.emit('messageLogged');

Итак, давайте зарегистрируем слушателя, который будет вызван, когда messageLogged поднят.
Посмотрите, у нас в объекте emitter есть метод addListener. Но для него есть alias, т.к. это событие используется очень часто. И этот алиас — on. Этот метод принимает два аргумента — первый — это название события. А второй, это callback функция, или сам слушатель. Эта функция будет вызвана, когда событие поднято.

emitter.on('messageLogged', () => {
    console.log('Listener called');
});

Весь код:

const EventEmitter = require('events');
const emitter = new EventEmitter();
//Register a listener
emitter.on('messageLogged', () => {
    console.log('Listener called');
});
//Raise an event
emitter.emit('messageLogged');

Само собой, здесь важен порядок, в котором объявлены слушатель и событие. Если мы объявим слушателя после события, то ничего не произойдет.

Event Arguments

Довольно часто, когда мы собираемся поднять событие, мы также хотим послать некоторые данные об этом событии. Например в нашем модуле логгере, когда мы логгируем данные, возможно, на удаленный сервис логгирования, мы будет генерировать id для этого сообщения. Мы собираемся вернуть этот id клиенту. Или оно может дать нам url, чтобы получить это сообщение напрямую.
Итак, когда событие поднято, мы можем добавить дополнительные аргументы, которые являются аргументами события. Допустим мы добавили id и url. Но как мы видим, эти волшебные (magic values) значение немного сбивают. Если вы хотите послать несколько данных о событии, считается лучшей практикой инкапсулировать все эти данные в объекте.

const EventEmitter = require('events');
const emitter = new EventEmitter();
//Register a listener
emitter.on('messageLogged', arg => {
    console.log('Listener called, ' arg);
});

//Raise an event
/**
 * @param  {event} 'messageLogged'
 * @param  {id} 1
 * @param  {url} 'url'
 */
// emitter.emit('messageLogged', 1, 'url');

emitter.emit('messageLogged', {id: 1, url: 'http://'});

Итак, когда мы зарегистрировали слушатель, мы указываем функцию слушатель, которая также принимает аргумент события. В общем, мы принимаем в колбэк параметр arg (мы можем назвать его как угодно), но по соглашению часто используется arg или e или eventArg.

Таким вот образом мы можем отослать данные о событии, которое произошло.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *