事件循环
事件驱动:node中程序的执行是由事件的发生和相应的事件处理器(eventHandler)来驱动的编程范式。
程序监听并响应发生的事件。每个异步事件都生成一个事件观察者,在执行某个事件(主题)结束的时候则触发这个事件上的处理函数(观察者)。【让我瞅瞅什么时候开始执行,例如点击事件后要打印一段文字,打印一段文字这个函数(观察者)时刻关注什么时候有了点击事件(主题)】
事件循环:
Node.js 单线程类似进入一个while(true)的事件循环,直到没有事件观察者退出,每个异步事件都生成一个事件观察者,如果有事件发生就调用该回调函数.
当web server接收到请求,就把它关闭然后进行处理,然后去服务下一个web请求。
当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户。
这个模型非常高效可扩展性非常强,因为 webserver 一直接受请求而不等待任何读写操作。(这也称之为非阻塞式IO或者事件驱动IO)
举个例子:
// 引入 events 模块
const events = require('events');
// 创建 eventEmitter 对象
const eventEmitter = new events.EventEmitter();
// 创建事件处理程序
const connectHandler = function connected() {
console.log('连接成功。');
// 触发 data_received 事件
eventEmitter.emit('data_received');
}
// 绑定 connection 事件处理程序
eventEmitter.on('connection', connectHandler);
// 使用匿名函数绑定 data_received 事件
eventEmitter.on('data_received', function(){
console.log('数据接收成功。');
});
// 触发 connection 事件
eventEmitter.emit('connection');
console.log("程序执行完毕。");
这段 Node.js 代码演示了如何使用 events
模块创建事件和事件处理程序。当事件被触发时,相关的事件处理程序会被执行。以下是代码的执行流程:
- 首先,创建了一个
EventEmitter
实例eventEmitter
,它用于处理事件的注册、触发和监听。 - 定义了一个名为
connectHandler
的事件处理程序,它会在connection
事件被触发时输出连接成功。
并且触发data_received
事件。 - 将
connectHandler
事件处理程序绑定到connection
事件上,这样当connection
事件被触发时,connectHandler
会被执行。 - 使用匿名函数绑定了
data_received
事件,该函数在data_received
事件被触发时输出数据接收成功。
。 - 触发了
connection
事件,这会导致connectHandler
被执行,输出连接成功。
并触发data_received
事件。 - 当
data_received
事件被触发时,匿名函数会被执行,输出数据接收成功。
。 - 最后,输出
程序执行完毕。
。
事件处理是异步的。当触发 connection
事件时,Node.js 将 connectHandler
和 data_received
事件放入事件队列,等待事件循环执行。因此,"程序执行完毕。"语句会在事件处理完成后才执行。
EventEmitter类
Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列,比如一个 fs.readStream 对象会在文件被打开的时候触发一个事件,这些产生事件的对象都是events.EventEmitter 的 实例。
对于每个事件,EventEmitter 支持 若干个事件监听器。
//event.js 文件
var events = require('events');
var emitter = new events.EventEmitter();
emitter.on('someEvent', function(arg1, arg2) {
console.log('listener1', arg1, arg2);
});
emitter.on('someEvent', function(arg1, arg2) {
console.log('listener2', arg1, arg2);
});
emitter.emit('someEvent', 'arg1 参数', 'arg2 参数');
//event.js 文件
var events = require('events');
var emitter = new events.EventEmitter();
emitter.on('someEvent', function(arg1, arg2) {
console.log('listener1', arg1, arg2);
});
// 和on方法一样
emitter.addListener('someEvent', function(arg1, arg2) {
console.log('listener2', arg1, arg2);
})
// 只会触发一次
emitter.once('someEvent', function(arg1, arg2) {
console.log('listener3', arg1, arg2);
})
emitter.emit('someEvent', 'arg1 参数', 'arg2 参数');
emitter.emit('someEvent', 'arg1 参数', 'arg2 参数');
移除某个监听器和移除全部。
//event.js 文件
var events = require('events');
var emitter = new events.EventEmitter();
// 只会触发一次
emitter.once('someEvent', function(arg1, arg2) {
console.log('listener1', arg1, arg2);
});
// 和on方法一样
emitter.addListener('someEvent', function(arg1, arg2) {
console.log('listener2', arg1, arg2);
})
const fun = function(arg1, arg2) {
console.log('listener3', arg1, arg2);
}
emitter.on('someEvent', fun)
emitter.emit('someEvent', 'arg1参数', 'arg2参数');
console.log(emitter.listeners('someEvent')); // listener1 不会再打印,因为执行一次就被删除了
emitter.removeListener('someEvent', fun) // 删除某个监听器
emitter.emit('someEvent', 'arg1参数', 'arg2参数');
emitter.removeAllListeners('someEvent');