Зачем использовать прослушиватели событий вместо вызовов функций? - PullRequest
10 голосов
/ 21 декабря 2010

В последнее время я изучаю слушателей событий и думаю, что наконец-то их понизил. По сути, это функции, которые вызываются для метода другого объекта. Мой вопрос: зачем создавать прослушиватель событий при вызове функции будет работать нормально?

Например, я хочу вызвать player.display_health (), и при его запуске метод player.get_health () должен быть запущен и сохранен, чтобы display_health () имел к нему доступ. Почему я должен использовать прослушиватель событий вместо простого вызова функции? Даже если display_health () был в другом объекте, это все равно не является проблемой для меня.

Если у вас есть другой пример, который лучше подходит для использования, пожалуйста, дайте мне знать. Возможно, некоторые языки не получают от этого особой пользы? (JavaScript, PHP, ASP?)

Ответы [ 5 ]

11 голосов
/ 21 декабря 2010

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

Например, возможно,Вы создаете библиотеку, которая будет использоваться другими людьми.Они не имеют исходного кода или каким-то образом не могут / не могут его изменять (или не должны).В вашей документации говорится, что определенные события возникают при определенных обстоятельствах.Затем они, в свою очередь, могут реагировать на эти события.

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

4 голосов
/ 21 декабря 2010

У меня вопрос: зачем создавать прослушиватель событий при вызове функции, все будет работать нормально?

Что если вы не знаете, какую функцию хотите вызвать?

Возьмите классический пример, кнопку, на которую пользователь может нажать. Тот, кто пишет в библиотеку, понятия не имеет , какую функцию вы хотите вызвать при нажатии кнопки. Это также было бы довольно непозволительно, если бы каждая кнопка могла вызывать одну и ту же функцию только при нажатии.

Таким образом, вместо этого вы можете прикрепить обработчик события к событию. Затем, когда событие инициируется, Button может делать то, что нужно, без необходимости точно знать во время компиляции, какую функцию он должен вызывать.

1 голос
/ 16 января 2019

Я думаю, что основная причина событий по сравнению с вызовами функций заключается в том, что события ' прослушиваются ', а вызовы ' made '.Таким образом, вызов функции всегда выполняется для другого объекта, тогда как слушатели ' выбирают ', чтобы прослушать событие, которое будет транслироваться от вашего объекта.Схема наблюдателя является хорошим исследованием для этой возможности.Вот краткий пример node.js, который иллюстрирует концепцию:

var events = require('events');
var Person = function(pname) {
    var name = pname;
};


var james = new Person('james');
var mary = new Person('mary');
var loudmouth = new Person('blabberer');

loudmouth.mouth = new events.EventEmitter();

//jame's observer.
james.read_lips = function(msg){
    console.log("james found out: " + msg);
};

//james adds his event to the emitter's event listener.
james.enter_elevator = function(){
    console.log('james is in the elevator');
    //NOTE: james adds HIMSELF as a listener for the events that may
    //transpire while he is in the elevator.
    loudmouth.mouth.on('elevator gossip', james.read_lips)
};

//james removes his event from the emitter when he leaves the elevator.
james.leave_elevator = function(){
    // read lips is how james responds to the event.
    loudmouth.mouth.removeListener('elevator gossip', james.read_lips);
    console.log('james has left the elevator');
};

//mary's observer
mary.overhear = function(msg){
    console.log("mary heard: " + msg);
};

//mary adds her observer event to the emitter's event listeners
mary.enter_elevator = function(){
    // overhear is how mary responds to the event.
    console.log('mary is in the elevator');
    //NOTE: now mary adds HERSELF to the listeners in the elevator and 
    //she observes using a different method than james which suits her.
    loudmouth.mouth.on('elevator gossip', mary.overhear);
};

loudmouth.speaks = function(what_is_said){
    console.log('loudmouth: ' + what_is_said);
    this.mouth.emit('elevator gossip', what_is_said);
};

james.enter_elevator();
mary.enter_elevator();
loudmouth.speaks('boss is having an affair');
james.leave_elevator();
loudmouth.speaks('just kidding');
console.log('james did not hear the last line because he was not listening anymore =)');

, поэтому в этой «истории» актеры предпочитают слушать или когда не слушать события от третьей стороны.Надеюсь, это поможет.

1 голос
/ 14 апреля 2018

Даже с подробными ответами выше, у меня все еще были проблемы с пониманием того, какова реальная разница между использованием контроллера / функций ИЛИ прослушивателя событий.

Одна из вещей, которая была пропущена во всех этих ответах, заключается в том, что использование Events и Event Listeners пригодятся, когда вы не хотите соединять свой код так близко . Каждая функция, класс и т. Д. Должны иметь единую цель.

Допустим, вы получили запрос API от постороннего. В моем случае моя точная проблема с пониманием этой концепции была, когда я получаю вызовы API от Stripe Webhooks.

Цель Stripe Webhooks: скажем, клиент тратит 10 000 долларов на ваш сайт. Ваша стандартная процедура - Аутентификация и Захват. Обновите БД, чтобы отразить их новый статус членства. В идеальном мире, и в случае нашей компании, 999/1000 раз, это идет отлично. Либо их карта будет отклонена на месте, либо платеж проходит. В обоих случаях мы отправляем им электронное письмо с уведомлением.

Но как насчет времени 1/1000, когда пользователь платит, а Stripe возвращает ошибку сбоя карты (что может быть разными)? В нашем случае мы отправляем им письмо по электронной почте и сообщаем им, что биллинг не прошел. Проблема, с которой мы столкнулись, заключается в том, что некоторые БАНКИ расследуют крупные платежи, которые возвращаются как Ошибка, но затем, через несколько минут, банк санкционирует платежи, и платеж фиксируется.

Так что же тут делать? Войдите в полоску Webhooks. Stripe Webhooks попадет на конечную точку API, если произойдет нечто подобное. На самом деле, Stripe Webhooks может использовать ваш API в любое время и в любой момент, когда платеж не был мгновенно подтвержден, получен, или если клиент запрашивает возврат.

Здесь слушатель событий пригодится. Полоса стреляет через POST с информацией о клиенте, а также тип Webhook. Теперь мы обработаем это, обновим базу данных и отправим им успешное письмо.

Но почему бы просто не использовать стандартный маршрут и контроллер? Причина, по которой мы не просто используем стандартный маршрут и контроллер, заключается в том, что нам нужно либо изменить уже определенные функции, классы и т. Д., Либо создать новую серию классов, которые связаны вместе, например, -> Stripe API Calls Received Обновление БД, Отправка электронной почты. Вместо того, чтобы связывать их вместе, мы используем приемник событий, чтобы сначала принять вызов API, а затем нажать на каждый из этих классов, функций и т. Д., Оставив все несвязанными.

Я искал повсюду, и я думаю, что документация Laravel объясняет это лучше всего. Когда я дал конкретный пример, я наконец понял, какова цель прослушивателя событий:

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

https://laravel.com/docs/5.6/events

1 голос
/ 05 августа 2017

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...