2.3 Node.js事件机制
学习目标
(1)理解Node.js的事件机制;
(2)掌握事件的监听与触发的用法。
文章目录
- 2.3 Node.js事件机制
- 什么是事件机制
- 为什么要有事件机制
- 事件循环
- 事件的监听与触发
- EventEmitter类常用API
什么是事件机制
Node.js的事件机制是一种高效的异步编程模型,通过事件循环和观察者模式来处理事件和异步操作,使得Node.js能够处理大量并发请求,并提供高性能的服务。
Node.js的事件机制使用了观察者模式
,其中事件是被观察的对象,而事件处理函数是观察者。当事件发生时,Node.js会通知所有注册了对应事件的观察者,并执行它们的事件处理函数。
为什么要有事件机制
通过事件机制,Node.js可以处理大量的并发请求,而不会阻塞主线程。它将异步操作转化为事件,通过事件驱动的方式来处理和响应这些操作,提高了系统的性能和可伸缩性。
事件循环
在Node.js中,事件循环是一个持续运行的循环,不断地检查事件队列是否有待处理的事件。当有事件发生时,Node.js会触发相应的事件,并将事件传递给注册的事件处理函数。
-
事件循环的六个阶段:事件循环包括六个阶段,分别是:timers(定时器),pending callbacks(待处理的回调),idle, prepare(空闲和准备),poll(轮询),check(检查),close callbacks(关闭回调)。
-
进入阶段并执行操作:事件循环进入某个阶段时,会执行该阶段特有的操作。例如,在timers阶段会执行定时器的回调函数,而在poll阶段会处理I/O事件等。
-
执行回调函数队列:在每个阶段中,事件循环会维持一个先进先出的可执行回调函数队列。事件循环会依次执行队列中的回调函数,直到队列结束或达到回调限制数。
-
切换到下一个阶段:当队列结束或达到回调限制数时,事件循环会切换到下一个阶段继续处理。这样循环进行,直到所有阶段都执行完毕。
-
检查非阻塞IO和定时器:在事件循环执行过程中,会检查是否有需要等待的非阻塞IO操作或定时器。如果没有需要等待的操作,事件循环将彻底结束。
总结:事件循环是一种按照特定顺序处理异步操作的机制。它通过六个阶段和回调函数队列来处理各种异步任务,直到所有任务都完成或没有需要等待的操作。这种机制能够提高程序的效率和响应性,使得异步编程更加简洁和可控。
事件的监听与触发
events 模块是 Node.js 的核心,Node.is 中大部分的模块都继承自 events 模块,events 模块只提供了一个EventEmitter 对象。
EventEmitter 类的核心就是事件触发与事件监听器功能的封装。所有能触发事件的对象都是EventEmitter类的实例。
当EventEmitter对象触发一个事件时,所有绑定在该事件上的函数会被同步地调用。下面以门卫报告有人来了为例简单示范事件的监听与触发,eventEmiter.on0方法用于注册监听器(有人来就报告).eventEmitter.emit0方法用于触发事件(发现有人来了)。
const EventEmitter = require('events'); //引入事件模块
const myEmitter = new EventEmitter.EventEmitter();//创建EventEmitter对象用于监听
//注册seen事件用于监视,有人来了就报告
myEmitter.on('seen', () => {
console.log('报告,有人来了');
});
myEmitter.emit('seen'); //触发(发射)seen事件进行报告
event.on方法用于注册监听器。emitter.emit方法用于触发事件。
EventEmitter类常用API
EventEmitter 类常用的API列举如下。
- EventEmitter.on(event , listener)、emitter.addListener(event , listener): 为指定事件注册一个监听器,参数 event 和listener 分别表示事件名称和回调函数。
- EventEmitter.once(event, listener):为指定事件注册一个单次监听器,即监听器最多触发一次触发后立刻解除该监听器。
- EventEmitter.emit(event,[arg1],[arg2],[…]): 触发由event 参数指定的事件,传递若干可选参数到事件监听器的参数表。
- EventEmiter.removeListener(event, listener): 删除指定事件的某个监听器,参数 listener必须是该事件已经注册过的监听器。
- emitter.listeners(event): 返回由 event 参数指定的事件的监听器的数组。
- emitter.setMaxListeners(n): 设置emitter 实例的最大事件监听数,默认是 10 个,设置0为不限制。
- emitter.removeAlListeners(event): 删除所有由 event 参数指定的事件的监听器
下面的例子演示如何为一个事件注册多个监听器。
const EventEmitter = require('events').EventEmitter; // 加载事件模块
var event = new EventEmitter(); // 实例化事件模块
// 注册事件(seen)
event.on('seen', function(who) {
console.log('报告,来人是一位', who);
});
// 再次注册事件(seen)
event.on('seen', function() {
console.log('欢迎光临!');
});
event.emit('seen', '女士'); // 发射(触发)事件(seen)
以上例子为事件 seen注册了两个事件监听器,然后触发了 seen 事件。从运行结果可以发现两个事件监听器回调函数被先后调用。