ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
>[success] # events模块 1. `Node`中的核心API都是基于异步事件驱动的,自带的`events`模块它可以用于处理**Node.js中的事件** 2. Node.js中的`events`模块就是一种**发布订阅(publish/subscribe)模式的实现**。`events`模块通过**EventEmitter类**实现了这种**发布订阅模式**,使得不同的模块之间可以**相互通信、传递消息,从而实现模块之间的高效耦合 在这个体系中**,某些对象(发射器(Emitters))发出某一个事件;我们可以监听这个事件(监听器 Listeners),并且传入的回调函数,这个回调函数会在监听到事件时调用; 3. 在实际开发中,events 模块常常被用来作为解耦合、扩展代码等方面 4. events模块 **优点的地方** | 优点 | 例子 | | --- | --- | | 异步处理 | 在Node.js中,I/O 操作是异步的操作,使用events模块可以方便地处理这些异步事件,从而提高系统的性能和可扩展性。例如,http服务器监听客户端请求事件('request'),或者文件系统触发读取文件完成事件('read')。 | | 灵活性 | 使用events模块时,可以自定义事件。例如,我们可以在设置同步操作成功或失败后触发一个'operation complete'事件,从而让其他模块更好地监听这个事件来执行相应的操作。 | | 易用性 | events模块提供了简单的API,例如on()和emit()来实现事件处理和触发。同时,它也提供了其他方便使用的方法,例如once()和removeListener()来监听和移除事件监听器。 | 5. events模块 **缺点的地方** | 缺点 | 例子 | | --- | --- | | 存在内存泄漏 | 如果我们没有正确地移除事件监听器,会导致内存泄漏。所以,我们必须注意在不再需要使用事件时,及时移除事件监听器。例如,在程序中使用 eventEmitter.on()监听事件,但是忘了使用eventEmitter.off()或者removeListener()移除监听器。 | | 可读性差 | 如果我们没有合理地使用events模块,例如定义过多的事件名称,可能会导致代码可读性较差,难以维护和修改。例如,定义了名为'operation complete','operation finished','task complete','work done'等多个事件名称,会导致事件名称的使用较为混乱。 | >[info] ## node 中常见使用 在 Node.js 中,有很多内置的 API 使用了 events 模块提供的事件机制。下面是一些常见的内置 API: * Stream:所有的可读流和可写流都是 EventEmitter 的实例,它们可以触发多个事件(如 'data' 事件,'end' 事件等),通知应用程序数据可用(或无法使用)等情况。 * HTTP 模块:HTTP 模块返回的服务器和客户端都是 EventEmitter 的实例,可以处理请求和响应事件以及错误和关闭事件。 * Child Processes(子进程):子进程的对象都是 EventEmitter 的实例,可以监听 'exit' 事件来检测子进程何时结束,以及 stdout 和 stderr 中的数据事件。 * File System 模块:文件操作模块也使用了事件,如读取文件时会触发 'data' 事件、'end' 事件等。 除此之外,还有一些其他的 Node.js API 使用了 events 模块,如`readline`模块、`dns`模块等。了解这些内置 API 使用的事件机制,可以帮助你更好地理解和应用 events 模块。 >[info] ## 常用的api 1. 使用常用的`api`之前需要先声明一个 `EventEmitter` 类,然后使用 `EventEmitter`类对外提供的`api` ~~~ const EventEmitter = require('events'); const eventEmitter = new EventEmitter(); ~~~ 2. 注册事件监听器 使用on()方法来注册一个事件监听器,语法如下: ~~~ eventEmitter.on(eventName, listener); ~~~ 其中eventName参数指定要监听的事件名称,listener参数是一个回调函数,当事件触发时会被调用。 3. 触发事件使用emit()方法来触发一个事件,语法如下: ~~~ eventEmitter.emit(eventName, [args]); ~~~ 其中 eventName参数指定要触发的事件名称,args参数是一个可选的数组,它包含传递给监听器的参数。 下面是一个简单的示例,演示了如何使用 events 模块: ~~~ const EventEmitter = require('events'); const eventEmitter = new EventEmitter(); //注册事件监听器 eventEmitter.on('eventName', function listener() { console.log('event has occurred'); }); //触发事件 eventEmitter.emit('eventName'); ~~~ 当运行这段代码时,控制台将输出 'event has occurred'。 * **常用api方法** | 方法名 | 参数 | 返回值 | 描述 | | --- | --- | --- | --- | | on(eventName, listener) / addListener(eventName, listener) | eventName: Stringlistener: Function | EventEmitter对象 | 监听事件,当对应的事件触发时,执行回调函数 | | once(eventName, listener) | eventName: Stringlistener: Function | EventEmitter对象 | 监听一次事件,事件被触发后将被删除 | | prependListener(eventName, listener) | eventName: Stringlistener: Function | EventEmitter对象 | 将监听事件添加到最前面 | | prependOnceListener(eventName, listener) | eventName: Stringlistener: Function | EventEmitter对象 | 将监听事件添加到最前面,但是只监听一次 | | removeListener(eventName, listener) | eventName: Stringlistener: Function(可选) | EventEmitter对象 | 移除事件监听器,若不指定listener则移除所有该事件的监听器 | | removeAllListeners(\[eventName\]) | eventName: String(可选) | EventEmitter对象 | 移除所有或指定事件的所有监听器 | | listeners(eventName) | eventName: String | Array | 返回指定事件的监听器数组 | | emit(eventName\[, ...args\]) | eventName: String...args: any | Boolean | 触发事件,调用对应事件的所有监听器并传入参数 | | off(eventName, listener) / removeListener(eventName, listener) | eventName: Stringlistener: Function(可选) | EventEmitter对象 | 移除事件监听器,与removeListener一样 | | eventNames() | | Array | 返回当前 EventEmitter对象注册的事件字符串数组 | | getMaxListeners() | | Number | 返回当前 EventEmitter对象的最大监听器数量,默认是10。可以通过setMaxListeners()方法修改 | | listenerCount(eventName) | eventName: String | Number | 返回当前 EventEmitter对象某一事件的监听器个数 | >[danger] ##### 案例 ~~~ const EventEmitter = require('events') const eventEmitter = new EventEmitter() // 定一个监听方法 function listener1(name, age) { console.log('监听器 listener1 执行', name, age) } function listener2(name, age) { console.log('监听器 listener1 执行', name, age) } // 注册监听事件 eventEmitter.on('onEvent', listener1) // 注册只触发一次的监听事件 eventEmitter.once('onEvent', listener2) // prependListener 设置监听器的优先级将给定的监听器函数添加到名为 eventName 的事件的监听器数组的开头。 eventEmitter.prependListener('onEvent', () => { console.log('我变成第一个触发的了prependListener') }) // 我虽然插到前面,但是我只触发一次 eventEmitter.prependOnceListener('onEvent', () => { console.log('我变成第一个触发的了prependOnceListener') }) // 触发事件 eventEmitter.emit('onEvent', '张三', 18) // 再次触发 eventEmitter.emit('onEvent', '张三', 18) ~~~ * 执行顺序 我变成第一个触发的了prependOnceListener 我变成第一个触发的了prependListener 监听器 listener1 执行 张三 18 监听器 listener1 执行 张三 18 我变成第一个触发的了prependListener 监听器 listener1 执行 张三 18 ~~~ const EventEmitter = require('events') const eventEmitter = new EventEmitter() // 定一个监听方法 function listener1(name, age) { console.log('监听器 listener1 执行', name, age) } function listener2(name, age) { console.log('监听器 listener2 执行', name, age) } // 注册监听事件 eventEmitter.on('onEvent', listener1) eventEmitter.on('onEvent', listener2) // 移除指定方法的监听事件 // eventEmitter.off('onEvent', listener1) //等同于removeListener eventEmitter.removeListener('onEvent', listener1) // 想移除所有的监听事件 // eventEmitter.removeAllListeners('onEvent') eventEmitter.emit('onEvent', '张三', 18) // 监听器 listener2 执行 张三 18 ~~~ ~~~ const EventEmitter = require('events') const eventEmitter = new EventEmitter() // 定一个监听方法 function listener1(name, age) { console.log('监听器 listener1 执行', name, age) } function listener2(name, age) { console.log('监听器 listener2 执行', name, age) } // 注册监听事件 eventEmitter.on('onEvent', listener1) eventEmitter.on('onEvent', listener2) // 打印监听器方法列表 const ls = eventEmitter.listeners('onEvent') console.log(ls) ~~~ ~~~ const EventEmitter = require('events') const eventEmitter = new EventEmitter() // 定一个监听方法 function listener1(name, age) { console.log('监听器 listener1 执行', name, age) } function listener2(name, age) { console.log('监听器 listener2 执行', name, age) } // 注册监听事件 eventEmitter.on('onEvent', listener1) eventEmitter.on('onEvent', listener2) eventEmitter.on('bbb', listener2) // 返回当前 EventEmitter对象注册的事件字符串数组 const ls = eventEmitter.eventNames() console.log(ls) // [ 'onEvent', 'bbb' ] ~~~ ~~~ const EventEmitter = require('events') const ee = new EventEmitter() ee.on("aaa", () => {}) ee.on("aaa", () => {}) ee.on("aaa", () => {}) ee.on('bbb', () => {}) ee.on('bbb', () => {}) // 1.获取所有监听事件的名称 console.log(ee.eventNames()) // 2.获取监听最大的监听个数 console.log(ee.getMaxListeners()) // 3.获取某一个事件名称对应的监听器个数 console.log(ee.listenerCount('aaa')) // 4.获取某一个事件名称对应的监听器函数(数组) console.log(ee.listeners('aaa')) ~~~