Шаблон Observer в Node.js или EventEmitter

Jun 15, 2018

Шаблон Observer определяет объект (субъект), который в состоянии уведомить своих наблюдателей (или обработчиков) об изменении своего состояния.

В отличие от коллбэков, у которых может быть лишь один обработчик, субъект способен иметь несколько наблюдателей.

В Node.js шаблон observer встроен в ядро и реализован на классе EventEmitter. EventEmitter дает возможно зарегистрировать одну или несколько функций, которые будут вызваны при появлении события определенного типа.

Получаем ссылку на класс:

const EventEmitter = require('events');
const myEmitter = new EventEmitter();
  • emitter.on(eventName, listener) - регистрируем обработчик для заданного типа событий (emitter.on)
  • emitter.once(eventName, listener) - регистрируем одноразовый обработчик: будет удален после первого же события (emitter.once)
  • emitter.removeListener(eventName, listener) - удаляем обработчика для события определенного типа
  • emitter.emit(eventName[, ...args]) - синхронно вызывает каждый обработчик на события с именем eventName

Все методы возвращают EventEmitter, что дает нам возможность составлять цепочки. this внутри обработчиков указывает на EventEmitter.

Пример использования EventEmitter

Создаем экземпляр EventEmitter и регистрируем обработчик:

// ./event_emitter.ts
const EventEmitter = require('events');
const myEventEmitter = new EventEmitter();

myEventEmitter.on('myTestEvent', function (p) {
    console.log('p - param on emit testEvent: ', p);
})

export { myEventEmitter };

В тестовых целях вызовем событие при добавлении посредством expressjs чего-либо в монго:

// ./base.ts
import { myEventEmitter } from '../event_emitter';

// Insert
insert = (req, res) => {
    
    // эмитим событие
    myEventEmitter.emit('myTestEvent', 'test_value_for_EMIT');

    const obj = new this.model(req.body);
    obj.save((err, item) => {
        if (err) {
            return console.error(err);
        }
        res.status(200).json(item);
    });
}

// p - param on emit testEvent:  test_value_for_EMIT
Добавить комментарий