1. events模块介绍
Node.js的events模块是一个基于发布/订阅模式的事件处理模块,用于监听和响应Node.js应用的事件。
事件:是一个异步的操作,在某个时间点触发,通常是由一些条件或者状态的变化而引发。事件可以被监听或响应,也可以被忽略。
在Node.js中,几乎所有的核心模块都继承自EventEmitter类,从而实现了事件的监听、触发和反馈。
2. EventEmitter类常用API
2.1 addListener
addListener
是EventEmitter
类中的一个方法,可以用来为指定的事件注册监听器。当事件被触发时,监听器会通过回调函数来处理。
const EventEmitter = require('events');
const myEmitter = new EventEmitter();
myEmitter.addListener('event', () => {
console.log('event 触发');
});
myEmitter.emit('event');
在上面的代码中,使用addListener
方法为myEmitter
对象注册了一个event
事件,当event
事件被触发时,console.log('event 触发')
会被执行。
2.2 on方法
on
方法和addListener
方法效果一样,都是用来为指定的事件注册监听器。
const EventEmitter = require('events');
const myEmitter = new EventEmitter();
myEmitter.on('event', () => {
console.log('event 触发');
});
myEmitter.emit('event');
2.3 once方法
once
方法和on
方法类似,都是用来为指定的事件注册监听器,不同的是,once
方法注册的监听器只会触发一次,触发后会被自动删除。
const EventEmitter = require('events');
const myEmitter = new EventEmitter();
myEmitter.once('event', () => {
console.log('event 触发');
});
myEmitter.emit('event');
myEmitter.emit('event');
在上面的代码中,once
方法注册的监听器只会触发一次,所以在第二次emit('event')
的时候不会有任何输出。
2.4 removeListener方法
removeListener
方法可以用来移除指定事件的某个监听器。需要注意的是,被移除的监听器必须是之前通过on
方法或addListener
方法注册的。
const EventEmitter = require('events');
const myEmitter = new EventEmitter();
const callback = () => {
console.log('event 触发');
};
myEmitter.on('event', callback);
myEmitter.emit('event');
myEmitter.removeListener('event', callback);
myEmitter.emit('event');
在上面的代码中,removeListener
方法移除了之前注册的监听器callback
,所以第二次emit('event')
的时候不会有任何输出。
2.5 removeAllListeners方法
removeAllListeners
方法可以用来移除指定事件的所有监听器。
const EventEmitter = require('events');
const myEmitter = new EventEmitter();
myEmitter.on('event', () => {
console.log('event 触发1');
});
myEmitter.on('event', () => {
console.log('event 触发2');
});
myEmitter.emit('event');
myEmitter.removeAllListeners('event');
myEmitter.emit('event');
在上面的代码中,第一次emit('event')
的时候,会先输出event 触发1
,然后再输出event 触发2
。而第二次emit('event')
的时候,由于之前注册的监听器都被移除了,所以不会有任何输出。
2.6 emit方法
emit
方法可以用来触发指定事件,所有注册了该事件的监听器都将会被调用执行。
const EventEmitter = require('events');
const myEmitter = new EventEmitter();
myEmitter.on('event', () => {
console.log('event 触发1');
});
myEmitter.on('event', () => {
console.log('event 触发2');
});
myEmitter.emit('event');
在上面的代码中,emit('event')
会触发所有注册了event
事件的监听器,所以会输出event 触发1
和event 触发2
。
3. 继承EventEmitter类
除了使用EventEmitter
类提供的API,我们还可以通过继承EventEmitter
类来创建自定义的事件。
const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
console.log('event 触发');
});
myEmitter.emit('event');
在上面的代码中,通过创建一个继承自EventEmitter
的类MyEmitter
,我们可以在MyEmitter
的实例对象中使用on
、emit
等方法。在myEmitter
对象中注册了一个event
事件,当event
事件被触发时,console.log('event 触发')
会被执行。
4. 事件和异步操作
由于事件是异步的操作,而Node.js是单线程的模型,所以在Node.js中,事件驱动非常重要。在事件驱动的模型中,当有事件触发时,Node.js会将事件交给事件循环处理器来进行处理。
下面我们通过一个例子来说明事件和异步操作之间的关系:
const fs = require('fs');
fs.readFile('./test.txt', (err, data) => {
if (err) {
throw err;
}
console.log(data.toString());
});
console.log('程序结束');
在上面的代码中,我们使用fs.readFile
方法读取了test.txt
文件,然后在回调函数中输出了文件的内容。由于读取文件是一个异步操作,所以当程序执行到console.log('程序结束')
时,文件读取往往还没有完成,所以输出结果如下:
程序结束
这是一个测试文件
可以看到,程序首先输出了程序结束
,而文件读取的结果却是在其后输出的。
5. 总结
events
模块是Node.js中非常重要的一个模块,它通过实现基于发布/订阅模式的事件处理机制,实现了Node.js的异步操作和事件驱动模型。
通过本文的介绍,我们了解了events
模块的常用API(addListener
、on
、once
、removeListener
、removeAllListeners
、emit
),以及如何继承EventEmitter
类创建自定义事件,同时还讨论了Node.js中事件和异步操作之间的关系。