Готовый перевод Node Up and Running / Node В начале... (рабочее название): --- Events
События
Первый функционал, который мы собираемся посмотреть это интерфейс событий. Потому что это основная, фундаментальная часть для работы каждого другого интерфейса. Благодаря хорошему пониманию данного функционала, вы будете способны использовать весь другой функционал эффективнее.
Если вы когда либо программировали на JavaScript в браузерах, вы раньше использовали события. Однако, модель событий использованная в браузерах приходит скорее из DOM, чем из самого JavaScript, и большинство концепций в DOM не имеют смысла за его контекстом. Давайте посмотрим в DOM модель событий и сравним с реализацией в Node. DOM имеет запускаемую пользователем событийную модель, основанную на взаимодействии пользователя с набором элементов интерфейса, расположенных в древовидной структуре(HTML, XML, и т.п.)
Это значит, что когда пользователь взаимодействует с конкретной частью интерфейса, есть событие и контекст элемента HTML/XML на который нажали или произвели иные действия.Этот контекст имеет родителя и потенциального потомка. Модель включает концепции распространения и перехвата, которые позволяют элементам посмотреть или вверх или вниз по дереву, чтобы получить событие, что было вызвано, контекст(объект) элемента является частью дерева.
Для примера, в HTML списке, событие нажатия на li может быть перехвачено слушателем(функцией, которая привязана к событию) на элементе ul, который его родитель.И наоборот, нажатие на ul может распространиться вниз на слушателя li.
Модель Node более проста, потому что JavaScript объекты не имеют такого вида древовидной структуры, как в браузерном JavaScript.
EventEmitter(Генератор событий)
Node создал класс EventEmitter, чтобы поддерживать некоторый базовый функционал событий, потому что событийная модель в браузерах привязана к DOM. Вес функционал событий в Node решается вокруг EventEmitter, потому что это также спроектировано быть классом-интерфейсом для других расширяющих его классов. Это бы было необычным вызывать непосредственно экземпляр EventEmitter.
EventEmitter имеет подручные методы, основные из них on и emit. Класс поддерживает эти методы для использования другими классами. Метод on создает слушателя на событие, как показано в пример 4-1.
Пример 4-1. Слушание события с помощью метода on.
Метод on получает два параметра: имя события для подслушивания и функцию(callback) для вызова, когда возбуждается событие. Класс наследующий от EventEmitter ожидается вызванный с новым ключевым словом, потому что является интерфейсом псевдокласса. Давайте посмотрим пример 4-2, чтобы увидеть как мы создаем новый класс как слушателя.
Пример 4-2. Создание нового класса поддерживающего события с EventEmitter.
Мы начинаем этот пример с подключения модуля util поэтому мы можем использовать наследованный метод. Наследование поддерживает путь добавления методов класса EventEmitter в класс Server, что мы создали. Это значит все новые экземпляры Server могут быть использованы как EventEmitter.
Мы тогда добавляем модуль events. Однако, мы хотим простой доступ к определенному классу EventEmitter внутри этого модуля. Заметьте как EventEmitter написан прописными буквами, чтобы показать, что это класс. Мы не используем метод createEventtEmitter, потому что мы не планируем использовать EventEmitter прямо. Мы просто хотим привязать его методы к классу Server, который мы собираемся создать.
Один раз мы подключили модуль, который нам нужен, следующий шаг создать наш базовый класс Server. Это предлагает одну простую функцию, которая записывает сообщения, когда сам запускается. В реальных реализациях, мы бы оформили класс Server прототипом с функциями, которые класс мог бы использовать. Для простоты, мы пропустили это. Важный шаг использовать sys.inherits(от себя, переименовали модуль sys теперь называется util), чтобы добавить EventEmitter как суперкласс нашему классу Server.
Когда мы хотим использовать класс Server, мы запускаем его с new Server(). Этот экземпляр класса Server будет иметь доступ к методам в суперкласса (EventEmitter), это значит, что мы можем добавить слушателя к нашему экземпляру используя метод on.
Прямо сейчас, однако, слушатель события, который мы добавили никогда не будет вызван, потому что событие abc не выстрелит. Мы можем исправить это добавлением кода в в пример 4-3, чтобы возбудить событие.
пример 4-3. Возбуждение событий
Стреляющий слушатель события такой простой как вызывание метода emit, который экземпляр Server наследовал от EventEmitter. Важно заметить, что эти события зависят от экземпляра. Здесь нет глобальных событий. Когда вы вызываете метод, вы привязываете к нему определенный объект базирующийся на классе EventEmitter. Даже различные экземпляры класса Server не могут раздавать события. S из кода в примере 4-3 не может раздаваться похожим событиям как другому экземпляру события, такой как однажды созданный с помощью var z = new Server();
Синтаксис функций обратного вызова.
Важная часть использования событий иметь дело с функциями обратного вызова. Глава 3 показывает лучшие практики в намного более глубже, но мы будем смотреть здесь в механизмы функций обратного вызова в Node. Они используют несколько стандартных шаблонов, но первое давай поговорим, что вероятнее.
Когда вызываем emit, в добавление названию события, вы также можете положить произвольный список параметров. Пример 4-4 включает три таких параметра. Здесь могут быть переданы в функцию слушающую событие. Когда вы получаете событие request от http сервера, для примера, вы получаете два параметра: req и res. Когда событие request было возбуждено, те параметры были переданы как второй и третий аргумент в функцию emit
Пример 4-4. Передача параметров, когда возбуждаем событие.
Это важно, чтобы понять как Node вызывает функции слушающие события, потому что это влияет на ваш стиль программирования. Когда emit() вызывается с аргументами, код в примере 4-5 используется, чтобы вызвать каждую функцию слушающую событие.
Пример 4-5. Вызов функции слушающей событие от emit
Этот код используется в обоих JavaScript методах для вызова функции из кода. Если emit() передается три или несколько аргументов, метод берет кратчайший путь и использует вызов. Иначе, он использует медленнее применение передачи всех аргументов как массив. Важная вещь для понимания, что Node делает в обоих этих вызовах использование этих аргументов прямо. Это значит, что контекст в котором слушатель события вызван есть контекст EventEmitter.- не их оригинальный контекст. Используя Node REPL, вы можете увидеть что происходит, когда вещи вызваны EventEmitter.
Пример 4-6. Изменения в контексте вызываются EventEmitter
Образец output сначала устанавливает класс Server. Включает функции для возбуждения события output. Метод outputThis привязывается к событию output как слушатель события. Когда мы возбуждаем событие output от различных областей видимости, мы находимся в области объекта EventEmitter, поэтому значение this, что outputThis открыл принадлежит EventEmitter. Следовательно, this переменная должна быть передана как параметр и присвоенной к переменной, если мы желаем сделать его использование в функции обратного вызова события.
Переведено на Нотабеноиде
http://notabenoid.org/book/30771/105674
Переводчики: rishatsharafiev
Настройки
Готово:
