Можете ли вы помочь мне легко понять динамические, абстрактные объекты событий?

StackOverflow https://stackoverflow.com/questions/471144

  •  19-08-2019
  •  | 
  •  

Вопрос

Я писал приложения, управляемые событиями, на C++, используя MFC для кнопок графического интерфейса, и использую события HTML, такие как onmousedown, для запуска Javascript на веб-странице.Идея событийно-ориентированного программирования интуитивно понятна, когда вы используете интерфейс и события жестко запрограммированы.

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

Моя проблема в том, чтобы перейти от времени компиляции к времени выполнения.Я говорю здесь о любом языке, но если вам нужен язык, выберите Javascript или PHP, поскольку я использую их чаще всего в наши дни.Я вообще не представляю, как можно использовать свой собственный объект события, чтобы что-то сделать.Это просто не та концепция, которую я понимаю.А поскольку я ими не пользуюсь, то не знаю, какова может быть их практическая польза.

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

Может ли кто-нибудь дать мне простое использование пользовательских событий?Или ситуации, когда это полезно или практично?Зависит ли это во многом от языка и среды, а также от того, как обрабатываются события?Ответ на Javascript был бы хорош, но я читаю много языков.

Извините, мне просто не хватает знаний в этом отношении, и мне нужно какое-то практическое, продвинутое (среднее?) понимание.Это как указатели в C.Я «понимаю» указатели и то, насколько они вам полезны.Но было время, когда я этого не делал, и многие люди, которых я знаю, до сих пор этого не делают.Как только вы это поймете, это будет просто, я просто не получаю таким образом специальные динамические события.

Это было полезно?

Решение

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

Вероятно, это мало что значит без хорошего примера, а хороших примеров, безусловно, много;Сомневаюсь, что мой будет лучшим из них, но тем не менее я попробую.Представьте себе два объекта.Один объект хочет знать, когда что-то происходит с другим объектом, чтобы он мог что-то сделать сам — возможно, семейная собака Ровер хочет поприветствовать папу у двери, когда он вернется с работы домой.Есть несколько способов запрограммировать этот сценарий, верно?

  • Убедитесь, что у папы есть ссылка на Ровер, и когда он придет домой, вызовите метод РовераприветствиеDatAtTheDoor() или

  • Дайте Rover ссылку на папу, послушайте папу на мероприятии onarrivehome, и когда он стреляет, позвоните в Greetdadatthedoor () внутри.

На первый взгляд может показаться, что между ними нет большой разницы, но на самом деле в папе есть часть реализации Ровера;если бы по какой-то причине реализацию Rover пришлось изменить, нам пришлось бы внести изменения в двух местах:один раз в Ровере, а потом еще раз в Папе.Возможно, это не так уж и важно, но все же не идеально.

А теперь представьте, что мама тоже хочет поприветствовать папу.И кот, г-н.Бигглсворт, который не очень любит папу, хочет убедиться, что его нет рядом, поэтому предпочитает выйти на улицу.А сосед Джо хочет знать, когда папа вернется домой, чтобы приставать к нему по поводу двадцати баксов, которые папа ему должен.Как нам учесть все эти сценарии и дополнительные, которые неизбежно возникнут?Размещение ссылок на мамин метод GreetingHusband(), кошачий метод getOutNow(), собачий методприветствиеDadAtTheDoor() и метод Джо goGetMyMoney() в определение папиного класса быстро испортит ситуацию для папы - и без веской причины, поскольку все Папе действительно нужно заняться собой, приехать домой.Мама, собака, кошка и сосед просто хотят получить уведомление, когда это произойдет, чтобы они могли делать все, что требуют их внутренние реализации.

Языки обрабатывают специфику этого материала по-разному, но, как вы увидите, когда начнете гуглить, схема обычно включает в себя массив или массивную структуру, на событии «Диспетчер» (в данном случае папа - т.е. объект, в котором интересуются все остальные) и «подписчики» (например, мама, кошка, ровер и Джо) все «регистрируются», вызвав общедоступный метод на диспетчере и передавая ссылки на себя - Ссылки, которые в некоторой форме оказываются в массиве «подписчиков» отца. Затем, когда папа приходит домой, он «отправляет» событие - «Я дома!» Событие, скажем, что, по сути, является функцией, которая зацикливается на каждом из своих подписчиков и вызывает их с некоторым общедоступным методом собственного - только это метод, которого не знает, чей папа не знает, не обязательно знает, потому что Слушатель предоставил это, когда он/она/это передал это.

Поскольку сейчас я в основном кодирую ActionScript, вот как это может выглядеть в моем мире — скажем, как объявлено в моем классе Mom:

var dad:Dad = new Dad();
dad.addEventListener(DadEvent.ARRIVED_HOME, greetHusbandAtDoor);

private function greetHusbandAtDoor(event:DadEvent):void
{
   // Go greet my husband
}

В случае с папой все, что мне нужно сделать, когда я приду домой, это:

dispatchEvent(new DadEvent(DadEvent.ARRIVED_HOME));

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

Надеюсь, это немного объясняет ситуацию — как выглядит событийное мышление, что означает слабая связь, почему это важно и так далее.Удачи!

Другие советы

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

Есть два аспекта создания функциональности с помощью событий. Первый - это определение условий, при которых будет происходить событие. В javascript в браузере нет ни одного & Quot; mousedown & Quot; событие. На самом деле есть один для каждого элемента на странице. В этом случае условие срабатывания любого из них зависит как от положения курсора мыши, так и от того, переключилась ли кнопка мыши из состояния «вверх» в состояние «вниз». Это условие может вызвать срабатывание нескольких событий. (В браузере есть нечто, называемое event & Quot; bubbling & Quot; это связано с этим. Но здесь это выходит за рамки).

Другим аспектом является обработчик событий. Событие происходит независимо от того, есть ли обработчик для него или нет. Предоставление обработчика зависит от вас. В javascript функции являются значениями первого класса. Они определяются во время выполнения, а не во время компиляции - так что нет необходимости в указателях или таблицах переходов. Вы создаете новую функцию во время выполнения и назначаете ее специальному свойству, которое среда хоста просматривает при возникновении определенного события.

поэтому при переполнении стека будет присутствовать обработчик событий для каждого из " onclick " events, которая превращает стрелку в красный цвет, уменьшает число, проверяет некоторую другую переменную и условно показывает уведомление. Затем, когда обработчик возвращается - он возвращает управление потоком в браузер, и аллилуйя, пользователь может снова взаимодействовать с браузером. (все взаимодействия прекращаются во время обработки события, поэтому лучше сделать это быстрее). Вот пример использования библиотеки jquery.

jQuery("a .downarrow")
.click(function(e){ e.target.style.color="red" /* ... do other things */ });

или в сыром javascript (версия 1.6) это может быть

Array.prototype.slice.apply(document.getElementsByTagName("a"))
.filter(function(o){ return !!(/downarrow/).exec(o.className)})
.forEach(function(o){ 
    o.onclick= function(e){ 
        e.target.style.color="red" /* ...do other things * / 
    }
 });

Это действительно так просто. Основная причина, по которой вы будете делать что-то подобное, - это возможность асинхронного взаимодействия. Приложение GUI не прогрессирует по прямой линии, шаг за шагом. Он должен динамически реагировать на ввод пользователя. События - это способ подделать внешний вид многопоточного приложения. Пользователь может увидеть, что многие вещи происходят одновременно, не прерывая друг друга.

Вы можете использовать библиотеку для определения пользовательского события. Это, возможно, закодирует какое-то доменное событие. Например: у вас есть игра в шахматы, которая думает о своем следующем ходу. процесс поиска хода заканчивается временем. Шахматная игра может запустить & Quot; onComputerMove & Quot; событие. Вы можете обработать это событие с помощью функции, которая захватывает спецификации для перемещения, обновляет визуальное представление шахматной доски, выдает сообщение пользователю и завершает работу. Затем, когда игрок перемещается, вы можете запустить & Quot; onPlayerMove & Quot; событие, которое делает то же самое.

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

Допустим, у меня есть два класса:Малышка и мамочка


Без событий я примерно вижу два способа позволить маме покормить ребенка:

  • мама звонит baby.pokeBelly() каждые полчаса звоните ребенку, чтобы узнать, нужно ли вам звонить baby.fillWith(milk).
    Проблема в том, что поток мамы должен ждать весь день после появления ребенка в цикле while.
  • Малыш узнает, что его родственная мамочка и позвонит mommy.feed(me) метод, который, в свою очередь, вызывает baby.fillWith(milk).
    Проблема тогда в том, что просишь простого малыша попросить правильную мамочку набить ему живот.
    Младенцы не делают этого, поскольку они должны оставаться простыми.

С помощью событий вы можете связать Mommy.OnBabyCries(baby) своему ребенку baby.Cry событие:

void Mommy.OnBabyCries(baby) {
    baby.fillWith(milk)
}

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

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

Я не знаю, полностью ли я понимаю ваш вопрос, но класс с событием похож на GUI с кнопкой. Просто подумайте об этом, как о гомонкуле ... Внутри каждого класса с событием есть маленький человек, который нажимает виртуальную кнопку. Он не знает, что будет делать кнопка, но знает, когда ее нажать. Теперь подумайте о связанном классе с другим маленьким человеком. Этот человек знает, что когда он слышит сообщение о нажатии кнопки, он должен что-то делать.

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

Я не знаю, помогает ли это, или я просто в странной поездке, думая о маленьких человечках в моих программах ...

В StackOverflow, когда вы голосуете против, ваша репутация падает, а стрелка вниз становится красной.

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

Вместо этого вы можете объявить onVoteDown событие, запустите его onclick и подпишитесь на это событие:

  • твоя репутация div
  • твоя стрела img
  • твой XmlHTTPRequest который отправляет ваш голос на сервер.

Я не совсем уверен, какой ответ вы ищете, поэтому прошу прощения, если это не что-то близкое.;)


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

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

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


Чтобы определить Действие...

События обычно устанавливаются через заранее определенные свойства объекта, например window.onload.По умолчанию все они равны undefined или null.Итак, чтобы их использовать, вам нужно присвоить им значение функции.

Вы можете использовать «анонимную» функцию:

window.onload = function (eventObject) {
    /* ... */
};

Или установите для них ссылку на функцию (не то же самое, но похожее на указатель):

function handleOnload(eventObject) {
    /* ... */
}

window.onload = handleOnload; /* note the lack of parenthesis */

Когда событие срабатывает, вызывается функция.Таким образом, в любой настройке, когда страница завершает загрузку, код, который вы размещаете вместо /* ... */ будет казнен.

Существуют также более формальные методы создания событий.W3C определяет addEventListener в то время как IE использует attachEvent. Больше информации.

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


Браузер обычно обрабатывает запуск событий – либо событий браузера (onload) или пользовательские события (onclick).Свойство и функция предназначены для реагирования.

Запуск собственное мероприятие – не самая простая задача.Чтобы полностью определить Event объект требует некоторой работы - и варьируется в зависимости от браузера.

Хотя, если вам это не нужно Event объект, вы можете просто вызвать событие:

window.onload();
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top