解释 Node.js 中的事件驱动编程
Node.js 中的事件驱动编程:与其他类似技术相比,Node.js 广泛使用事件,这是其速度背后的原因之一。一旦我们启动了一个 Node.js 服务器,它就会初始化变量和函数,然后监听事件的发生。
事件驱动编程用于同步多个事件的发生,并使程序尽可能简单。事件驱动程序的基本组成部分是:
- 触发事件时调用回调函数(称为事件处理程序)。
- 一个事件循环,用于侦听事件触发器并为该事件调用相应的事件处理程序。
侦听事件触发的函数称为“观察者”。它在事件发生时被触发。 Node.js 提供了一系列已经内置的事件。这些“事件”可以通过“事件”模块和 EventEmitter 类访问。 Node.js 的大部分内置模块都继承自 EventEmitter 类
EventEmitter: EventEmitter 是一个允许对象相互通信的 Node 模块。 Node 的异步事件驱动架构的核心是 EventEmitter。许多 Node 的内置模块都继承自 EventEmitter。
这个想法很简单——发射器对象发送命名事件,触发已经注册的监听器。因此,发射器对象具有两个关键特征:
- 发射名称事件:发生某事的信号称为发射事件。发射对象的状态变化通常是这种情况的原因。
- 注册和注销监听函数:是指回调函数与其对应事件的绑定和解除绑定。
事件驱动编程原则:
- 一套用于处理事件的函数。这些可以是阻塞的或非阻塞的,具体取决于实现。
- 将注册函数绑定到事件。
- 当接收到注册事件时,事件循环会轮询新事件并调用匹配的事件处理程序。
实现:文件名:app.js
Javascript
// Import the 'events' module
const events = require('events');
// Instantiate an EventEmitter object
const eventEmitter = new events.EventEmitter();
// Handler associated with the event
const connectHandler = function connected() {
console.log('Connection established.');
// Trigger the corresponding event
eventEmitter.emit('data_received');
}
// Binds the event with handler
eventEmitter.on('connection', connectHandler);
// Binds the data received
eventEmitter.on(
'data_received', function () {
console.log('Data Transfer Successful.');
});
// Trigger the connection event
eventEmitter.emit('connection');
console.log("Finish");
上面的代码片段将名为“connectHandler”的处理程序与事件“connection”绑定在一起。触发事件时触发回调函数。
使用以下命令运行app.js文件:
node app.js
输出:
Connection established.
Data Transfer Successful.
Finish
事件驱动编程的优点:
- 灵活性:在需要时更容易更改代码部分。
- 图形界面的适用性:它允许用户直接从工具栏中选择工具(如单选按钮等)
- 编程简单:支持预测编码,提高了程序员的编码体验。
- 容易找到自然分界线:单元测试基础设施的自然分界线很容易找到。
- 对系统建模的好方法:对必须是异步和反应性的系统建模的有用方法。
- 允许更多交互式程序:它支持更多交互式程序。几乎所有最新的 GUI 应用程序都使用事件驱动编程。
- 使用硬件中断:可以通过硬件中断来实现,降低计算机的功耗。
- 允许传感器和其他硬件:它使传感器和其他硬件与软件通信变得简单。
事件驱动编程的缺点:
- 复杂:简单的程序变得不必要地复杂。
- 不合逻辑且不明显:程序的流程通常不合逻辑且更明显
- 难以发现错误:调试事件驱动程序很困难
- 令人困惑:程序中的太多表单可能会让程序员感到困惑和/或沮丧。
- 紧密耦合:事件模式将与模式的消费者紧密耦合。
- 阻塞:操作的复杂阻塞。
事件驱动编程和面向对象编程之间的关系:我们可以将面向对象编程(OOP)和事件驱动编程(EDP)结合起来,在同一个代码片段中一起使用。
当 OOP 与 EDP 一起使用时:
- 所有 OOP 基础(封装、继承和多态性)都被保留。
- 对象能够发布事件通知并订阅来自其他对象的事件通知。
如何区分 OOP 有无 EDP:对象之间的控制流就是 OOP 有无 EDP 的区别。在没有 EDP 的 OOP 中的方法调用中,控制从一个对象流向另一个对象。一个对象的主要函数是调用其他对象的方法。
但是,在事件通知中,带有 EDP 的 OOP 中的控制从一个对象转移到另一个对象。对象订阅来自其他对象的通知,等待来自这些对象的通知,根据通知执行工作,然后发布自己的通知。