Порядок срабатывания обработчиков



Все обработчики событий срабатывают синхронно в том порядке, в котором зарегистрированы. Вызов метода on объекта-эмиттера событий называют регистрацией обработчика событий.

Допустим, посетителям, которые пришли с запросом отправки документа send, после обработки этого запроса требуется ещё оплатить отправку документа через кассу. Это реализуется несколькими способами. И один из них — добавить дополнительный обработчик:

emitterObject.on('send', Handler.send); emitterObject.on('send', Handler.pay);

 

Важно не забыть добавить соответствующую функцию в класс Handler:

static pay() { console.log(`Customer needs to pay for the services`); }

 

Теперь если придёт посетитель с запросом send, то в терминале появится следующий результат обработки такого запроса:

Send request Customer needs to send a document Customer needs to pay for the services

При этом обработчики будут срабатывать каждый раз, когда приходит посетитель с соответствующим запросом.

Класс EventEmitter также даёт возможность выполнить обработчик один раз, а потом автоматически снять его с регистрации. Для этого он предоставляет метод once, используемый вместо on:

emitterObject.on('send', Handler.send); emitterObject.once('send', Handler.pay);

 

Тогда заплатить придётся только первому посетителю, который пришёл с запросом send.

Удаление обработчика

Зарегистрированный обработчик также удаляется вручную. Для этого класс EventEmitter предоставляет метод removeListener. Например, если отправка документов вдруг стала бесплатной, то потребуется убрать обработчик Handler.pay:

emitterObject.removeListener('send', Handler.pay);

 

Этот метод удаляет за один раз не более одного обработчика.

Важно! Если событие уже сгенерировано, вызов метода removeListener не повлияет на обработчиков, пока последний из них не отработает. Для следующих событий указанный обработчик уже запускаться не будет.

Максимальное количество обработчиков

По умолчанию при создании более 10 обработчиков для одного события класс EventEmitter покажет предупреждение. Это количество можно изменить для конкретного экземпляра класса посредством метода setMaxListeners. Если в него передать 0, то количество будет неограниченным:

emitterObject.setMaxListeners(0);

Обработка ошибок

Для обработки ошибок предусматривается специальное событие error. Оно, как и другие события, генерируется самостоятельно. Если для события error не будет ни одного обработчика, программа выбросит исключение, покажет stack trace и завершит работу.

Например, генерирование события без подключённого обработчика:

emitterObject.emit('error', new Error('Что-то пошло не так!'));

 

Завершит программу примерно с таким сообщением:

events.js:174 throw er; // Unhandled 'error' event ^ Error: Что-то пошло не так! at Object.<anonymous> (/home/user/Documents/test.js:8:29) at Module._compile (internal/modules/cjs/loader.js:778:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10) at Module.load (internal/modules/cjs/loader.js:653:32) at tryModuleLoad (internal/modules/cjs/loader.js:593:12) at Function.Module._load (internal/modules/cjs/loader.js:585:3) at Function.Module.runMain (internal/modules/cjs/loader.js:831:12) at startup (internal/bootstrap/node.js:283:19) at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3) Emitted 'error' event at: at Object.<anonymous> (/home/user/Documents/test.js:8:15) at Module._compile (internal/modules/cjs/loader.js:778:30) [... lines matching original stack trace ...] at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3)

Важно! Всегда обрабатываем события ошибок.

  1. Решите задачу по выводу данных в консоль.
console.log('Record 1'); setTimeout(() => { console.log('Record 2'); Promise.resolve().then(() => { setTimeout(() => { сonsole.log('Record 3'); Promise.resolve().then(() => { console.log('Record 4'); });    }); });  }); console.log('Record 5'); Promise.resolve().then(() => Promise.resolve().then(() => console.log('Record 6')));

 

Глоссарий

Блокирующие операции ввода-вывода — операции ввода-вывода, блокирующие поток выполнения программы до тех пор, пока операция не закончится.

Макрозадачи — задачи вроде setTimeout, setInterval, операции ввода-вывода и т. д.

Микрозадачи — задачи вроде методов объектов Promise (then, catch, finally) или process.nextTick. Не относится к циклу событий, а принадлежит к движку V8. Выполняются в отдельной очереди задач, сразу после завершения текущей фазы цикла событий.

Многопоточный сервер создаёт новый поток для каждого входящего запроса от клиента.

Неблокирующие операции ввода-вывода — операции ввода-вывода, которые не блокируют поток выполнения программы из-за выгрузки таких операций в ядро системы.

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

Однопоточный сервер принимает все входящие запросы от клиентов в один поток.

Рекурсия — это функция, вызывающая саму себя.

Событийно-ориентированная архитектура — паттерн, лежащий в основе большей части Node.js-модулей. Заключается в активном использовании концепции событий — когда специальные объекты генерируют события, а специальные функции-обработчики реагируют на них, выполняя заданные инструкции.

Цикл событий — механизм на основе библиотеки libuv, который позволяет Node.js выполнять неблокирующие операции ввода-вывода, возвращающие по мере выполнения данные, через систему колбэков.

Эмиттер события (emit — излучать) — это специальный объект, генерирующий различные события.

Libuv — библиотека, написанная на C. Реализует цикл событий, выгрузку асинхронных операций ввода-вывода в систему и отвечает за кросс-платформенность для неблокирующей работы с операциями ввода-вывода.

Tick — выполнение каждой из 6 фаз цикла событий.

 

Дополнительные материалы

  1. Официальная документация.
  2. Исходный код библиотеки libuv.
  3. Генератор псевдослучайных чисел.
  4. Метод Math.random().

Используемые источники

  1. Официальная документация.
  2. Проблема С10k.
  3. Документация по JavaScript от Mozilla.

 


Дата добавления: 2021-12-10; просмотров: 15; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!