事件驱动的编程 - node.js,Java

问题描述:

我来自Java,但最近一直在做一些Node.js,并且一直在研究Node中的EventEmitter模块。事件驱动的编程 - node.js,Java

我不明白的是事件驱动的编程和“常规”编程之间的根本区别。

这里有一些伪代码来展示我对“事件驱动”编程的想法。

EventEmitter ee = new EventEmitter(); 
Function f = new SpecialFunction(); 

ee.on('grovel',f); 

ee.emit('grovel'); //calls function 'f' 

的EventEmitter对象似乎是在做是建立一个事件的String表示之间以及与响应的功能的散列关系(在这种情况下“拜倒”)的唯一的工作。似乎就是这样,这里没有太多的魔法。但是,我的问题是 - 事件驱动的编程如何真正在低级事件(如鼠标点击和打字)的幕后工作?换句话说,我们如何在程序中点击并将其变成一个字符串(如'grovel')?

+0

你提到的代码在服务器上,而你正在寻找的东西所在客户端。在客户端,您可以捕获这些事件,然后调用服务器来处理这些事件。我相信你听说过Front-side JavaScript和流行的JQuery。 – Ravi 2014-12-19 09:20:53

+1

没有。我们不会点击并变成一个字符串 – 2014-12-19 11:09:03

好的。我会试试这个。

使用事件发射器有几个主要原因。

其中一个主要原因是浏览器是JavaScript诞生的地方,有时会强迫你。无论你是直接将你的事件连接到你的HTML,使用jQuery或其他框架/库,或其他任何东西,底层代码仍然基本相同(erm,基本上...)

所以首先,如果你想反应到键盘或鼠标事件,就像你提到的,你可能只是很难直接绑定到事件处理程序(回调)这样的:

<div onclick="myFunc(this)">Click me</div> 

...或者你可以通过DOM做同样的事情在JS参考:

document.getElementById('my_element').onclick = function (evt) { 
    alert('You clicked me'); 
}; 

这曾经是我们连线的主要方式u点击处理程序。这种模式的一个致命缺点是您只能为每个DOM事件附加一个回调。如果您想要对同一个事件做出反应的第二个回调函数,则需要将它合并到现有的点击处理函数中,或者构建一个委托函数来处理调用这两个函数的工作。另外,事件发送器最终与事件监听器紧密耦合,这通常是一件坏事。

随着应用程序变得越来越复杂,使用事件侦听器变得更有意义。浏览器厂商(最终)在一个单一的方式来做到这一点解决:

// Build the handler 
var myHandler = function (evt) { 
    alert('You clicked me too'); 
    window.myHandlerRef = this; // Watch out! See below. 
}; 

// Bind the handler to the DOM event 
document.getElementById('my_element').addEventListener('click', myHandler); 

这种模式的好处是,你可以将多个处理程序,以一个单一的DOM事件,或从几个不同的DOM事件调用一个单一的事件处理程序。缺点是你必须小心不要泄漏:取决于你如何编写它们,事件处理闭包(如上面的myHandler)可能在它们所连接的DOM元素已被销毁和GC化后继续存在。这意味着最好总是练习removeEventListener('click', myHandler)。 (一些图书馆有一个off()方法可以做同样的事情)。

这种模式非常适用于键盘事件,以及:

var giveUserAHeadache = function (evt) { 
    alert('Annoying, isn\'t it?'); 
}; 

document.addEventListener('keypress', giveUserAHeadache); 

好。这就是你通常处理本地浏览器事件的方式。但开发人员也喜欢在自己的代码中使用这种事件委派模式。您希望这样做的原因是,您可以尽可能地解耦您的代码。

例如,在用户界面中,每当用户的浏览器脱机时都会发出一个事件(例如,您可能会看到navigator.onLine)。也许你可以在你的页眉上有一个绿色/红色的灯来显示在线状态,也许你可以在离线状态下禁用所有提交按钮,也可以在页脚中显示警告信息。通过事件监听器/发射器,您可以将所有这些模块编写为完全解耦的模块,并且仍然可以锁定步骤工作。如果你需要重构你的用户界面,你可以移除一个组件(例如灯),将其替换为别的东西,而不用担心其他模块中的逻辑搞乱了。

作为另一个例子,在Node应用程序中,您可能希望数据库代码向特定控制器发出错误状况并记录错误 - 也可能发送电子邮件。你可以看到如何迭代地添加这些类型的东西。通过事件监听器,这种事情很容易做到。

您可以自己写,也可以使用您特定环境中可用的任何模式。 jQuery,Angular,Ember和Node都有他们特定的方法,但你也可以*构建自己的 - 这是我鼓励你尝试的方法。

这些都是相同的基本思想的所有变化,有很多模糊的确切定义或最正确的实现(实际上,有些人可能会质疑,如果这些都是不同的)。但这里是主要的罪魁祸首:

  1. Observer
  2. Pub-Sub
  3. Mediator