你能让我轻易理解动态,抽象的事件对象吗?

时间:2022-04-22 00:06:55

I've written C++ event-driven apps using MFC for GUI buttons, and I use HTML events like onmousedown to trigger some Javascript in a webpage. The idea of event-driven programming is intuitive when you are using the interface and events are hard-coded.

我使用MFC为GUI按钮编写了C ++事件驱动的应用程序,我使用像onmousedown这样的HTML事件来触发网页中的一些Javascript。当您使用接口并且事件是硬编码时,事件驱动编程的想法是直观的。

I know how to use a function pointer in C, and I see how Windows uses them to run an event loop. I can write code to dynamically call a different function.

我知道如何在C中使用函数指针,我看到Windows如何使用它们来运行事件循环。我可以编写代码来动态调用不同的函数。

My problem is, moving away from compile-time and into runtime. I'm talking any language here, but if you need a language, choose Javascript, or PHP as I use them most these days. I don't have a grasp at all of how I might use my own event object to get something done. It's just not a concept I get. And since I don't use them, I don't know what their practical use might be.

我的问题是,从编译时转移到运行时。我在这里谈论任何语言,但如果你需要一种语言,那么选择Javascript或PHP,因为我最近使用它们。我完全没有掌握如何使用自己的事件对象来完成某些事情。这不是我得到的概念。由于我不使用它们,我不知道它们的实际用途是什么。

For example, I suppose that if I wanted to make a custom turn-based game, that I might use event objects to represent an effect of some game-piece ability that just needs to "happen."

例如,我想如果我想制作一个自定义回合制游戏,那么我可能会使用事件对象来表示某些游戏片段能力的影响,只需要“发生”。

Can someone give me a simple use of custom events? Or situations where it is useful or practical? Does it depend largely on the language and environment and how events are handled? A Javascript answer would be good, but I read many languages.

有人能给我一个简单的自定义事件吗?还是有用或实用的情况?它在很大程度上取决于语言和环境以及如何处理事件?一个Javascript答案会很好,但我读了很多语言。

Sorry I am just deficient in this regard and need some practical, advanced (intermediate?) insight. It's like pointers in C. I "get" pointers and how they are your friend. But there was a time where I didn't, and many people I know still don't. It's simple once you get it, I just don't get custom, dynamic events that way.

对不起,我只是缺乏这方面的东西,需要一些实用,先进(中级?)的见解。它就像C中的指针一样。我“得到”指针以及它们如何成为你的朋友。但有一段时间我没有,而我认识的许多人仍然没有。一旦你得到它就很简单,我就是不会那样获得自定义的动态事件。

6 个解决方案

#1


When we talk about event-oriented programming, we're usually talking about one or more implementations of the observer design pattern. And one goal of the observer design pattern is to achieve loose coupling between objects.

当我们谈论面向事件的编程时,我们通常会谈论观察者设计模式的一个或多个实现。观察者设计模式的一个目标是实现对象之间的松散耦合。

That probably doesn't mean much without a good example, and there are certainly lots of good ones out there; I doubt mine will be the best of them, but I'll take a whack at it nonetheless. Imagine two objects. One object wants to know when something happens with the other object, so it can do something itself -- maybe the family dog, Rover, wants to greet Dad at the door when he gets home from work. There are a couple of ways you might program that scenario, right?

如果没有一个很好的例子,这可能并不意味着什么,而且肯定有很多好的例子;我怀疑我的将是他们中最好的,但我仍会对它进行打击。想象一下两个物体。一个物体想要知道什么时候发生了与另一个物体发生的事情,所以它本身可以做一些事情 - 也许家里的狗,罗孚,当他下班回家时想要在门口迎接爸爸。您可以通过两种方式对该方案进行编程,对吧?

  • Make sure Dad has an reference to Rover, and when he comes home, call Rover's greetDatAtTheDoor() method, or

    确保爸爸有一个参考罗孚,当他回家时,打电话给罗孚的greetDatAtTheDoor()方法,或者

  • Give Rover a reference to dad, listen for Dad's onArriveHome event, and when it fires, call greetDadAtTheDoor() internally.

    给Rover一个对爸爸的引用,听爸爸的onArriveHome事件,当它激活时,在内部调用greetDadAtTheDoor()。

On the surface, there might not seem to be much difference between the two, but actually, Dad has some of Rover's implementation burned into him; if Rover's implementation had to change for some reason, we'd have to make changes in two places: once in Rover, and then again in Dad. Not a huge deal, maybe, but still, not ideal.

从表面上看,两者之间似乎没有太大区别,但实际上,爸爸已经将罗孚的一些实施方式烧成了他;如果罗孚的实施因某种原因不得不改变,我们必须在两个地方做出改变:一次是在罗孚,一次是在爸爸。也许并不是一件大事,但仍然不理想。

Now imagine Mom wants to greet Dad as well. And the cat, Mr. Bigglesworth, who doesn't like Dad very much, wants to make sure he's not around, so he'd rather go outside. And a neighbor, Joe, wants to know when Dad gets home, so he can bug him about that twenty bucks Dad owes him. How do we account for all those scenarios, and the additional ones that'll inevitably crop up? Placing references to Mom's greetHusband() method, the cat's getOutNow() method, the dog's greetDadAtTheDoor() method, and Joe's goGetMyMoney() method into Dad's class definition would mess things up fast for Dad -- and for no good reason, since all Dad really needs to do, himself, is come home. Mom, the dog, the cat, and the neighbor just want to be notified when that happens, so they can do whatever their internal implementations require.

现在想象妈妈也想和爸爸打招呼。那只猫,Bigglesworth先生,他不太喜欢爸爸,想要确保他不在身边,所以他宁愿出门。一个邻居乔想知道爸爸什么时候回家,所以他可以告诉他爸爸欠他的二十块钱。我们如何解释所有这些情景,以及其他不可避免的情况?放置对妈妈的greetHusband()方法的引用,cat的getOutNow()方法,狗的greetDadAtTheDoor()方法和Joe的goGetMyMoney()方法进入爸爸的类定义会让爸爸快速搞砸 - 并且没有充分的理由,因为所有爸爸真的需要做,自己,回家。妈妈,狗,猫和邻居只是希望在发生这种情况时得到通知,因此他们可以做任何内部实施所需的事情。

Languages handle the specifics of this stuff in different ways, but as you'll see when you start Googling around, the pattern usually involves there being an array, or array-like structure, on the event "dispatcher" (in this case, Dad -- i.e., the object everyone else is interested in), and the "subscribers" (e.g., Mom, the cat, Rover, and Joe) all "register" by calling a publicly exposed method on the dispatcher and passing in references to themselves -- references that end up, in some form, in Dad's array of "subscribers." Then, when Dad comes home, he "dispatches" an event -- the "I'm home!" event, say -- which is essentially a function that loops over each of his subscribers and invokes them with some publicly accessible method of their own -- only it's a method whose name Dad doesn't know, doesn't have to know, because the listener provided it when he/she/it passed it in.

语言以不同的方式处理这些东西的细节,但正如你将看到开始使用Google搜索时,模式通常涉及在事件“调度程序”(在这种情况下,爸爸)上有一个数组或类似数组的结构 - 即,其他人都感兴趣的对象),并且“订阅者”(例如,妈妈,猫,流浪者和乔)都通过在调度员上调用公开暴露的方法并将引用传递给他们自己来“注册” - 以某种形式出现在爸爸的“订阅者”数组中的引用。然后,当爸爸回家时,他“派遣”了一个活动 - “我回家了!”事件,比如说 - 这实际上是一个循环遍历每个订阅者的函数,并使用他们自己的一些可公开访问的方法调用它们 - 只有它是一个名字爸爸不知道的方法,不必知道,因为当他/她/它通过时,听众提供了它。

Since I happen to code mostly ActionScript these days, here's how it might look in my world -- say, as declared from within my Mom class:

由于我最近几乎编写了ActionScript代码,所以这就是它在我的世界中的样子 - 比如,从我的妈妈类中声明:

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

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

In Dad, then, all I have to do, when I come home, is:

那么,在爸爸,当我回到家时,我所要做的就是:

dispatchEvent(new DadEvent(DadEvent.ARRIVED_HOME));

... and because Flash handles the event-dispatching and notification details for me (again, everyone does it a bit differently, but internally, Flash follows the conceptual model I've described), my Dad comes home, and each family member does what it signed up to do automatically.

...并且因为Flash为我处理事件调度和通知细节(同样,每个人都有点不同,但在内部,Flash遵循我描述的概念模型),我的爸爸回家了,每个家庭成员都做它注册了什么自动做。

Hopefully that explains things a bit -- what event-thinking looks like, what loose coupling means, why it's important, and so on. Best of luck!

希望这能解释一下 - 事件思维是什么样的,松散耦合意味着什么,它为什么重要,等等。祝你好运!

#2


In a compiled langauge, you write your own event loop. In a runtime language, it's implemented by the host environment already, and the programmer only gets an abstracted interface into the events system. You never see the event loop.

在已编译的语言中,您可以编写自己的事件循环。在运行时语言中,它已经由主机环境实现,并且程序员只获得事件系统中的抽象接口。你永远不会看到事件循环。

There's two facets to building functionality with events. The first is defining the conditions under which an event will fire. In javascript in a browser, there isn't a single "mousedown" event. There's in fact one for every element on the page. In this case, the condition for when any of them will fire is based both on the location of the mouse cursor, and whether the mouse button has just switched from the up state to the down state. This condition may cause multiple events to fire. (In the browser, there's something called event "bubbling" that's related to this. but that's out of scope here).

使用事件构建功能有两个方面。第一个是定义事件触发的条件。在浏览器的javascript中,没有一个“mousedown”事件。事实上,页面上的每个元素都有一个。在这种情况下,它们中的任何一个将触发的条件是基于鼠标光标的位置,以及鼠标按钮是否刚刚从向上状态切换到向下状态。这种情况可能会导致多个事件触发。 (在浏览器中,有一个叫做“冒泡”的东西,与此有关。但这里的范围超出了范围)。

The other facet is the event handler. An event happens regardless of whether there's a handler for it or not. Providing the handler is up to you. In javascript, functions are first class values. They get defined at runtime, not at compile time- So there's no need for pointers or jump tables. You create a new function at run time, and you assign it to a special property that the host environment looks up when a particular event fires.

另一个方面是事件处理程序。无论是否存在处理程序,都会发生事件。提供处理程序取决于您。在javascript中,函数是第一类值。它们在运行时定义,而不是在编译时定义 - 因此不需要指针或跳转表。您在运行时创建一个新函数,并将其分配给主机环境在特定事件触发时查找的特殊属性。

so on stack overflow, there will be an event handler on each of the down arrow's "onclick" events, which turns the arrow red, decrements a number, checks some other variable and conditionally shows a notification. Then when the handler returns- it returns control of the thread to the browser, and hallelujah the user can interact with the browser again. (all interactions cease while an event is handled, so you'd better make it quick). Here's an example using the jquery library.

所以在堆栈溢出时,每个向下箭头的“onclick”事件都会有一个事件处理程序,它会将箭头变为红色,减少数字,检查其他变量并有条件地显示通知。然后当处理程序返回时 - 它将线程的控制权返回给浏览器,并且hallelujah用户可以再次与浏览器交互。 (在处理事件时,所有交互都会停止,因此您最好快速完成)。这是使用jquery库的示例。

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

or in raw javascript (version 1.6) it may be

或者在原始的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 * / 
    }
 });

It really is that simple. The main reason you would do something like this is it allows asynchronous interaction. A gui application doesn't progress in a straight line, step by step. It has to respond dynamically to the user's input. Events are a way to kind of fake the appearance of a multithreaded application. It can look to the user that many things are happening simultaneously without interrupting eachother.

它真的很简单。你会做这样的事情的主要原因是它允许异步交互。 gui应用程序不会一步一步地直线前进。它必须动态响应用户的输入。事件是一种伪造多线程应用程序外观的方法。它可以让用户看到许多事情同时发生而不会中断彼此。

You could use a library to define a custom event. This would perhaps encode some domain specific event. For example: you have a chess game that is thinking about its next move. the process for searching for the move runs out of time. The chess game could fire a "onComputerMove" event. You could handle that event with a function that grabs the specifications for the move, and updates the visual representation of the chessboard, and pops up a message for the user, and exits. Then when the player moves you can fire a "onPlayerMove" event, which does much of the same thing.

您可以使用库来定义自定义事件。这可能会编码某些特定于域的事件。例如:你有一个国际象棋游戏正在考虑它的下一步行动。搜索移动的过程耗尽时间。国际象棋游戏可以发起“onComputerMove”事件。您可以使用捕获移动规范的函数来处理该事件,并更新棋盘的可视化表示,并为用户弹出消息,然后退出。然后,当玩家移动时,你可以发起一个“onPlayerMove”事件,这会做同样的事情。

#3


The most wonderful thing about events is that is reduce bidirectional explicit coupling between two modules or classes.

事件最精彩的是减少两个模块或类之间的双向显式耦合。

So let say I have two classes: Baby and Mommy

所以说我有两个班:宝贝和妈妈


Without events, I roughly see two methods to allow a Mommy to feed a Baby:

没有事件,我粗略地看到两种方法让妈妈喂宝宝:

  • mommy calls the baby.pokeBelly() method on the Baby each half hour to know if you have to call baby.fillWith(milk).
    The problem is that Mommy's thread have to wait all day after the baby in a while loop
  • 妈妈每隔半小时给宝宝打电话给baby.pokeBelly()方法,知道你是否要打电话给baby.fillWith(牛奶)。问题是,妈妈的线程必须在婴儿进入一段时间后整天等待

  • Baby know its associated Mommy and call a mommy.feed(me) method, which in turn calls baby.fillWith(milk).
    The problem is then that ask a simple baby to ask the right mommy to fill its belly.
    Babies don't do that as they should stay simple.
  • 宝贝知道它的相关妈咪,并打电话给妈妈。喂(我)方法,后者又称为baby.fillWith(牛奶)。问题是,请一个简单的宝宝问正确的妈妈填饱肚子。婴儿不这样做,因为他们应该保持简单。


With events, you could bind a Mommy.OnBabyCries(baby) to its babie's baby.Cry event:

通过活动,你可以将一个Mommy.OnBabyCries(宝宝)绑定到它的宝宝的宝宝.Cry事件:

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

After this, if baby wants to eat, all it has to do is raise its Cry event.

在此之后,如果宝宝想吃东西,它所要做的就是提高它的哭泣事件。

The logic stays in the Mommy, or even later in any Babysitter, and Baby stays happy, without having to worry.

逻辑保留在妈妈身上,甚至在任何保姆中都会存在,婴儿保持快乐,而不必担心。

#4


I don't know if I totally understand your question but a class with an event is just like an GUI with a button. Just think about it like a homonculus...Inside every class with an event there's a little person with a virtual button to press. He doesn't know what the button will do, but he knows when to press it. Now think of a related class with another little person in it. That person knows that when he hears a message that a button was pressed, he's supposed to do something.

我不知道我是否完全理解你的问题,但是一个带有事件的类就像一个带按钮的GUI。想想它就像一个同性恋......在每个有活动的班级里面都有一个带虚拟按钮的小人物。他不知道按钮会做什么,但他知道何时按下它。现在想起一个与其他小人物相关的课程。那个人知道,当他听到按下按钮的消息时,他应该做点什么。

Anytime you want the second guy to know about something the first guy did, you connect the switchboard between the first class and the second class (Subscribe to the event). When the first guy presses the button (fires the event), the second guy does whatever he knows he's supposed to do...

任何时候你想让第二个人知道第一个人所做的事情,你就可以在第一个班级和第二个班级之间连接交换机(订阅活动)。当第一个人按下按钮(发射事件)时,第二个人会做任何他知道他应该做的事情......

I don't know if this helps or I'm just on an acid trip thinking of little tiny people in my programs...

我不知道这是否有帮助,或者我只是在考虑我的程序中的小人物的酸性旅行...

#5


At *, when you vote down, your reputation falls and your down arrow turns red.

在*中,当您拒绝投票时,您的声誉会下降,而您的向下箭头会变为红色。

Usually, you write a single onclick, update all elements in it, and try not to forget to change it every time when page layout changes.

通常,您编写单个onclick,更新其中的所有元素,并且每次页面布局更改时都不要忘记更改它。

Instead, you may declare onVoteDown event, fire it in onclick and subscribe to this event:

相反,您可以声明onVoteDown事件,在onclick中触发它并订阅此事件:

  • your reputation div
  • 你的声誉div

  • your arrow img
  • 你的箭头img

  • your XmlHTTPRequest that sends your vote to the server.
  • 您的XmlHTTPRequest将您的投票发送到服务器。

#6


I'm not entirely sure what sort of answer you're looking for, so I apologize if this isn't anything close. ;)

我不完全确定你正在寻找什么样的答案,所以如果这不是什么关系,我道歉。 ;)


By custom, do you mean custom actions, custom triggers, or truly custom events?

通过自定义,您是指自定义操作,自定义触发器还是真正的自定义事件?

E.g.: A custom action would respond to a pre-defined event (say, a mouse click), a custom trigger would be faking a mouse click via script, and a custom event would be a listener that's not defined by the language or isn't readily available.

例如:自定义操作将响应预定义的事件(例如,鼠标单击),自定义触发器将通过脚本伪造鼠标单击,自定义事件将是未被语言定义的侦听器或isn'随时可用。

If you're looking for custom events, I can't really help you. Though, I don't think there's much support for them in JavaScript.

如果您正在寻找自定义活动,我无法真正帮助您。虽然,我认为JavaScript中对它们的支持并不多。


To define an Action...

定义一个动作......

Events are normally established via pre-defined properties of an object, say window.onload. By default, they are all equal to undefined or null. So, to put them to use, you have to set them to the value of a function.

事件通常通过对象的预定义属性建立,比如window.onload。默认情况下,它们都等于undefined或null。因此,要使用它们,您必须将它们设置为函数的值。

You can use an "anonymous" function:

您可以使用“匿名”功能:

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

Or set them to a function reference (not the same, but similar to a pointer):

或者将它们设置为函数引用(不同,但类似于指针):

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

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

When the event is triggered, the function is called. So, in either setup, when the page finishes loading, the code you place instead of /* ... */ will be executed.

触发事件时,将调用该函数。因此,在任一设置中,当页面完成加载时,将执行您放置的代码而不是/ * ... * /。

There's also more formal methods available for creating events. W3C defines addEventListener while IE uses attachEvent. More info.

还有更多正式的方法可用于创建事件。当IE使用attachEvent时,W3C定义了addEventListener。更多信息。

There are plenty of references available for learning the list of available events. Here's 2 that should give you a good base:

有很多参考资料可用于学习可用事件列表。这里有2个应该给你一个很好的基础:


The browser usually handles the triggering of events -- either for browser events (onload) or user events (onclick). The property and function are meant to respond.

浏览器通常处理事件的触发 - 对于浏览器事件(onload)或用户事件(onclick)。属性和功能是为了响应。

Triggering your own event isn't the easiest thing to accomplish. To completely define an Event object takes some work -- and varies between browsers.

触发您自己的事件并不是最容易实现的事情。要完全定义Event对象需要一些工作 - 并且在浏览器之间有所不同。

Though, if you don't need the Event object, you can simply call the event:

但是,如果您不需要Event对象,则可以简单地调用该事件:

window.onload();

#1


When we talk about event-oriented programming, we're usually talking about one or more implementations of the observer design pattern. And one goal of the observer design pattern is to achieve loose coupling between objects.

当我们谈论面向事件的编程时,我们通常会谈论观察者设计模式的一个或多个实现。观察者设计模式的一个目标是实现对象之间的松散耦合。

That probably doesn't mean much without a good example, and there are certainly lots of good ones out there; I doubt mine will be the best of them, but I'll take a whack at it nonetheless. Imagine two objects. One object wants to know when something happens with the other object, so it can do something itself -- maybe the family dog, Rover, wants to greet Dad at the door when he gets home from work. There are a couple of ways you might program that scenario, right?

如果没有一个很好的例子,这可能并不意味着什么,而且肯定有很多好的例子;我怀疑我的将是他们中最好的,但我仍会对它进行打击。想象一下两个物体。一个物体想要知道什么时候发生了与另一个物体发生的事情,所以它本身可以做一些事情 - 也许家里的狗,罗孚,当他下班回家时想要在门口迎接爸爸。您可以通过两种方式对该方案进行编程,对吧?

  • Make sure Dad has an reference to Rover, and when he comes home, call Rover's greetDatAtTheDoor() method, or

    确保爸爸有一个参考罗孚,当他回家时,打电话给罗孚的greetDatAtTheDoor()方法,或者

  • Give Rover a reference to dad, listen for Dad's onArriveHome event, and when it fires, call greetDadAtTheDoor() internally.

    给Rover一个对爸爸的引用,听爸爸的onArriveHome事件,当它激活时,在内部调用greetDadAtTheDoor()。

On the surface, there might not seem to be much difference between the two, but actually, Dad has some of Rover's implementation burned into him; if Rover's implementation had to change for some reason, we'd have to make changes in two places: once in Rover, and then again in Dad. Not a huge deal, maybe, but still, not ideal.

从表面上看,两者之间似乎没有太大区别,但实际上,爸爸已经将罗孚的一些实施方式烧成了他;如果罗孚的实施因某种原因不得不改变,我们必须在两个地方做出改变:一次是在罗孚,一次是在爸爸。也许并不是一件大事,但仍然不理想。

Now imagine Mom wants to greet Dad as well. And the cat, Mr. Bigglesworth, who doesn't like Dad very much, wants to make sure he's not around, so he'd rather go outside. And a neighbor, Joe, wants to know when Dad gets home, so he can bug him about that twenty bucks Dad owes him. How do we account for all those scenarios, and the additional ones that'll inevitably crop up? Placing references to Mom's greetHusband() method, the cat's getOutNow() method, the dog's greetDadAtTheDoor() method, and Joe's goGetMyMoney() method into Dad's class definition would mess things up fast for Dad -- and for no good reason, since all Dad really needs to do, himself, is come home. Mom, the dog, the cat, and the neighbor just want to be notified when that happens, so they can do whatever their internal implementations require.

现在想象妈妈也想和爸爸打招呼。那只猫,Bigglesworth先生,他不太喜欢爸爸,想要确保他不在身边,所以他宁愿出门。一个邻居乔想知道爸爸什么时候回家,所以他可以告诉他爸爸欠他的二十块钱。我们如何解释所有这些情景,以及其他不可避免的情况?放置对妈妈的greetHusband()方法的引用,cat的getOutNow()方法,狗的greetDadAtTheDoor()方法和Joe的goGetMyMoney()方法进入爸爸的类定义会让爸爸快速搞砸 - 并且没有充分的理由,因为所有爸爸真的需要做,自己,回家。妈妈,狗,猫和邻居只是希望在发生这种情况时得到通知,因此他们可以做任何内部实施所需的事情。

Languages handle the specifics of this stuff in different ways, but as you'll see when you start Googling around, the pattern usually involves there being an array, or array-like structure, on the event "dispatcher" (in this case, Dad -- i.e., the object everyone else is interested in), and the "subscribers" (e.g., Mom, the cat, Rover, and Joe) all "register" by calling a publicly exposed method on the dispatcher and passing in references to themselves -- references that end up, in some form, in Dad's array of "subscribers." Then, when Dad comes home, he "dispatches" an event -- the "I'm home!" event, say -- which is essentially a function that loops over each of his subscribers and invokes them with some publicly accessible method of their own -- only it's a method whose name Dad doesn't know, doesn't have to know, because the listener provided it when he/she/it passed it in.

语言以不同的方式处理这些东西的细节,但正如你将看到开始使用Google搜索时,模式通常涉及在事件“调度程序”(在这种情况下,爸爸)上有一个数组或类似数组的结构 - 即,其他人都感兴趣的对象),并且“订阅者”(例如,妈妈,猫,流浪者和乔)都通过在调度员上调用公开暴露的方法并将引用传递给他们自己来“注册” - 以某种形式出现在爸爸的“订阅者”数组中的引用。然后,当爸爸回家时,他“派遣”了一个活动 - “我回家了!”事件,比如说 - 这实际上是一个循环遍历每个订阅者的函数,并使用他们自己的一些可公开访问的方法调用它们 - 只有它是一个名字爸爸不知道的方法,不必知道,因为当他/她/它通过时,听众提供了它。

Since I happen to code mostly ActionScript these days, here's how it might look in my world -- say, as declared from within my Mom class:

由于我最近几乎编写了ActionScript代码,所以这就是它在我的世界中的样子 - 比如,从我的妈妈类中声明:

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

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

In Dad, then, all I have to do, when I come home, is:

那么,在爸爸,当我回到家时,我所要做的就是:

dispatchEvent(new DadEvent(DadEvent.ARRIVED_HOME));

... and because Flash handles the event-dispatching and notification details for me (again, everyone does it a bit differently, but internally, Flash follows the conceptual model I've described), my Dad comes home, and each family member does what it signed up to do automatically.

...并且因为Flash为我处理事件调度和通知细节(同样,每个人都有点不同,但在内部,Flash遵循我描述的概念模型),我的爸爸回家了,每个家庭成员都做它注册了什么自动做。

Hopefully that explains things a bit -- what event-thinking looks like, what loose coupling means, why it's important, and so on. Best of luck!

希望这能解释一下 - 事件思维是什么样的,松散耦合意味着什么,它为什么重要,等等。祝你好运!

#2


In a compiled langauge, you write your own event loop. In a runtime language, it's implemented by the host environment already, and the programmer only gets an abstracted interface into the events system. You never see the event loop.

在已编译的语言中,您可以编写自己的事件循环。在运行时语言中,它已经由主机环境实现,并且程序员只获得事件系统中的抽象接口。你永远不会看到事件循环。

There's two facets to building functionality with events. The first is defining the conditions under which an event will fire. In javascript in a browser, there isn't a single "mousedown" event. There's in fact one for every element on the page. In this case, the condition for when any of them will fire is based both on the location of the mouse cursor, and whether the mouse button has just switched from the up state to the down state. This condition may cause multiple events to fire. (In the browser, there's something called event "bubbling" that's related to this. but that's out of scope here).

使用事件构建功能有两个方面。第一个是定义事件触发的条件。在浏览器的javascript中,没有一个“mousedown”事件。事实上,页面上的每个元素都有一个。在这种情况下,它们中的任何一个将触发的条件是基于鼠标光标的位置,以及鼠标按钮是否刚刚从向上状态切换到向下状态。这种情况可能会导致多个事件触发。 (在浏览器中,有一个叫做“冒泡”的东西,与此有关。但这里的范围超出了范围)。

The other facet is the event handler. An event happens regardless of whether there's a handler for it or not. Providing the handler is up to you. In javascript, functions are first class values. They get defined at runtime, not at compile time- So there's no need for pointers or jump tables. You create a new function at run time, and you assign it to a special property that the host environment looks up when a particular event fires.

另一个方面是事件处理程序。无论是否存在处理程序,都会发生事件。提供处理程序取决于您。在javascript中,函数是第一类值。它们在运行时定义,而不是在编译时定义 - 因此不需要指针或跳转表。您在运行时创建一个新函数,并将其分配给主机环境在特定事件触发时查找的特殊属性。

so on stack overflow, there will be an event handler on each of the down arrow's "onclick" events, which turns the arrow red, decrements a number, checks some other variable and conditionally shows a notification. Then when the handler returns- it returns control of the thread to the browser, and hallelujah the user can interact with the browser again. (all interactions cease while an event is handled, so you'd better make it quick). Here's an example using the jquery library.

所以在堆栈溢出时,每个向下箭头的“onclick”事件都会有一个事件处理程序,它会将箭头变为红色,减少数字,检查其他变量并有条件地显示通知。然后当处理程序返回时 - 它将线程的控制权返回给浏览器,并且hallelujah用户可以再次与浏览器交互。 (在处理事件时,所有交互都会停止,因此您最好快速完成)。这是使用jquery库的示例。

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

or in raw javascript (version 1.6) it may be

或者在原始的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 * / 
    }
 });

It really is that simple. The main reason you would do something like this is it allows asynchronous interaction. A gui application doesn't progress in a straight line, step by step. It has to respond dynamically to the user's input. Events are a way to kind of fake the appearance of a multithreaded application. It can look to the user that many things are happening simultaneously without interrupting eachother.

它真的很简单。你会做这样的事情的主要原因是它允许异步交互。 gui应用程序不会一步一步地直线前进。它必须动态响应用户的输入。事件是一种伪造多线程应用程序外观的方法。它可以让用户看到许多事情同时发生而不会中断彼此。

You could use a library to define a custom event. This would perhaps encode some domain specific event. For example: you have a chess game that is thinking about its next move. the process for searching for the move runs out of time. The chess game could fire a "onComputerMove" event. You could handle that event with a function that grabs the specifications for the move, and updates the visual representation of the chessboard, and pops up a message for the user, and exits. Then when the player moves you can fire a "onPlayerMove" event, which does much of the same thing.

您可以使用库来定义自定义事件。这可能会编码某些特定于域的事件。例如:你有一个国际象棋游戏正在考虑它的下一步行动。搜索移动的过程耗尽时间。国际象棋游戏可以发起“onComputerMove”事件。您可以使用捕获移动规范的函数来处理该事件,并更新棋盘的可视化表示,并为用户弹出消息,然后退出。然后,当玩家移动时,你可以发起一个“onPlayerMove”事件,这会做同样的事情。

#3


The most wonderful thing about events is that is reduce bidirectional explicit coupling between two modules or classes.

事件最精彩的是减少两个模块或类之间的双向显式耦合。

So let say I have two classes: Baby and Mommy

所以说我有两个班:宝贝和妈妈


Without events, I roughly see two methods to allow a Mommy to feed a Baby:

没有事件,我粗略地看到两种方法让妈妈喂宝宝:

  • mommy calls the baby.pokeBelly() method on the Baby each half hour to know if you have to call baby.fillWith(milk).
    The problem is that Mommy's thread have to wait all day after the baby in a while loop
  • 妈妈每隔半小时给宝宝打电话给baby.pokeBelly()方法,知道你是否要打电话给baby.fillWith(牛奶)。问题是,妈妈的线程必须在婴儿进入一段时间后整天等待

  • Baby know its associated Mommy and call a mommy.feed(me) method, which in turn calls baby.fillWith(milk).
    The problem is then that ask a simple baby to ask the right mommy to fill its belly.
    Babies don't do that as they should stay simple.
  • 宝贝知道它的相关妈咪,并打电话给妈妈。喂(我)方法,后者又称为baby.fillWith(牛奶)。问题是,请一个简单的宝宝问正确的妈妈填饱肚子。婴儿不这样做,因为他们应该保持简单。


With events, you could bind a Mommy.OnBabyCries(baby) to its babie's baby.Cry event:

通过活动,你可以将一个Mommy.OnBabyCries(宝宝)绑定到它的宝宝的宝宝.Cry事件:

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

After this, if baby wants to eat, all it has to do is raise its Cry event.

在此之后,如果宝宝想吃东西,它所要做的就是提高它的哭泣事件。

The logic stays in the Mommy, or even later in any Babysitter, and Baby stays happy, without having to worry.

逻辑保留在妈妈身上,甚至在任何保姆中都会存在,婴儿保持快乐,而不必担心。

#4


I don't know if I totally understand your question but a class with an event is just like an GUI with a button. Just think about it like a homonculus...Inside every class with an event there's a little person with a virtual button to press. He doesn't know what the button will do, but he knows when to press it. Now think of a related class with another little person in it. That person knows that when he hears a message that a button was pressed, he's supposed to do something.

我不知道我是否完全理解你的问题,但是一个带有事件的类就像一个带按钮的GUI。想想它就像一个同性恋......在每个有活动的班级里面都有一个带虚拟按钮的小人物。他不知道按钮会做什么,但他知道何时按下它。现在想起一个与其他小人物相关的课程。那个人知道,当他听到按下按钮的消息时,他应该做点什么。

Anytime you want the second guy to know about something the first guy did, you connect the switchboard between the first class and the second class (Subscribe to the event). When the first guy presses the button (fires the event), the second guy does whatever he knows he's supposed to do...

任何时候你想让第二个人知道第一个人所做的事情,你就可以在第一个班级和第二个班级之间连接交换机(订阅活动)。当第一个人按下按钮(发射事件)时,第二个人会做任何他知道他应该做的事情......

I don't know if this helps or I'm just on an acid trip thinking of little tiny people in my programs...

我不知道这是否有帮助,或者我只是在考虑我的程序中的小人物的酸性旅行...

#5


At *, when you vote down, your reputation falls and your down arrow turns red.

在*中,当您拒绝投票时,您的声誉会下降,而您的向下箭头会变为红色。

Usually, you write a single onclick, update all elements in it, and try not to forget to change it every time when page layout changes.

通常,您编写单个onclick,更新其中的所有元素,并且每次页面布局更改时都不要忘记更改它。

Instead, you may declare onVoteDown event, fire it in onclick and subscribe to this event:

相反,您可以声明onVoteDown事件,在onclick中触发它并订阅此事件:

  • your reputation div
  • 你的声誉div

  • your arrow img
  • 你的箭头img

  • your XmlHTTPRequest that sends your vote to the server.
  • 您的XmlHTTPRequest将您的投票发送到服务器。

#6


I'm not entirely sure what sort of answer you're looking for, so I apologize if this isn't anything close. ;)

我不完全确定你正在寻找什么样的答案,所以如果这不是什么关系,我道歉。 ;)


By custom, do you mean custom actions, custom triggers, or truly custom events?

通过自定义,您是指自定义操作,自定义触发器还是真正的自定义事件?

E.g.: A custom action would respond to a pre-defined event (say, a mouse click), a custom trigger would be faking a mouse click via script, and a custom event would be a listener that's not defined by the language or isn't readily available.

例如:自定义操作将响应预定义的事件(例如,鼠标单击),自定义触发器将通过脚本伪造鼠标单击,自定义事件将是未被语言定义的侦听器或isn'随时可用。

If you're looking for custom events, I can't really help you. Though, I don't think there's much support for them in JavaScript.

如果您正在寻找自定义活动,我无法真正帮助您。虽然,我认为JavaScript中对它们的支持并不多。


To define an Action...

定义一个动作......

Events are normally established via pre-defined properties of an object, say window.onload. By default, they are all equal to undefined or null. So, to put them to use, you have to set them to the value of a function.

事件通常通过对象的预定义属性建立,比如window.onload。默认情况下,它们都等于undefined或null。因此,要使用它们,您必须将它们设置为函数的值。

You can use an "anonymous" function:

您可以使用“匿名”功能:

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

Or set them to a function reference (not the same, but similar to a pointer):

或者将它们设置为函数引用(不同,但类似于指针):

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

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

When the event is triggered, the function is called. So, in either setup, when the page finishes loading, the code you place instead of /* ... */ will be executed.

触发事件时,将调用该函数。因此,在任一设置中,当页面完成加载时,将执行您放置的代码而不是/ * ... * /。

There's also more formal methods available for creating events. W3C defines addEventListener while IE uses attachEvent. More info.

还有更多正式的方法可用于创建事件。当IE使用attachEvent时,W3C定义了addEventListener。更多信息。

There are plenty of references available for learning the list of available events. Here's 2 that should give you a good base:

有很多参考资料可用于学习可用事件列表。这里有2个应该给你一个很好的基础:


The browser usually handles the triggering of events -- either for browser events (onload) or user events (onclick). The property and function are meant to respond.

浏览器通常处理事件的触发 - 对于浏览器事件(onload)或用户事件(onclick)。属性和功能是为了响应。

Triggering your own event isn't the easiest thing to accomplish. To completely define an Event object takes some work -- and varies between browsers.

触发您自己的事件并不是最容易实现的事情。要完全定义Event对象需要一些工作 - 并且在浏览器之间有所不同。

Though, if you don't need the Event object, you can simply call the event:

但是,如果您不需要Event对象,则可以简单地调用该事件:

window.onload();