文章目录
一、Node.js事件循环
Node.js是单进程单线程
应用程序,但是因为V8引擎提供的异步执行回调接口,通过这些接口可以处理大量的并发,所以性能非常高。
Node.js几乎每一个API都是支持回调函数
的。
Node.js基本上所有的事件机制都是用设计模式中观察者模式实现
Node.js单线程类似进入一个while(true)的事件循环,直到没有事件观察者退出,每个异步事件都生成一个事件观察者,如果有事件发生就调用该回调函数
二、事件驱动程序
Node.js使用事件驱动模型
,当Web server接受到请求,就把它关闭然后进行处理,然后去服务下一个web请求。当这个请求完成后,它被放回处理队列,当到达队列开头,这个结果被返回给用户。
这个模型非常高效可扩展性非常强,因为webserver一直接受请求而不等待任何读写操作。(这也称为非阻塞式IO或者事件驱动IO)
在事件驱动模型中,会生成一个主循环来监听事件,当检测到事件时触发回调函数。
注意:线程是整个程序的最小单位,即一个程序就是一个进程,一个进程里至少要运行一个线程。
在Node.js的事件机制中主要有三类角色:事件(Event)、事件发射器(EventEmitter)、事件监听器(EventListener)
Node.js 有多个内置的事件,我们可以通过引入 events 模块,并通过实例化 EventEmitter 类来绑定和监听事件。例如:
//引入events模块
var events = require('events');
//创建eventEmitter对象
var eventEmitter = new events.EventEmitter();
//绑定事件及事件的处理程序
eventEmitter.on('eventName',eventHandler);
//触发事件
eventEmitter.emit('eventName');
三、事件触发器
Node.js 的大部分核心 API 都是围绕惯用的异步事件驱动架构构建的,在该架构中,某些类型的对象(称为"触发器")触发命名事件,使 Function 对象(“监听器”)被调用。
EventEmitter类
:事件发射器,也叫事件触发器,所有可能触发事件的对象都是一个集成了EventEmitter类的子类的实例对象,这些对象暴露了 eventEmitter.on() 函数,允许将一个或多个函数绑定到对象触发的命名事件。 通常,事件名称是驼峰式字符串,但也可以使用任何有效的 JavaScript 属性键。
当 EventEmitter 对象触发事件时,所有绑定到该特定事件的函数都会被同步地调用。 被调用的监听器返回的任何值都将被忽略和丢弃。
EventEmitter 按照注册的顺序同步
地调用所有监听器。 这确保了事件的正确排序,并有助于避免竞争条件和逻辑错误。 在适当的时候,监听器函数可以使用 setImmediate() 或 process.nextTick() 方法切换到异步的操作模式。
1、EventEmitter类
EventEmitter 类由 events 模块定义和暴露:
const EventEmitter = require('events');
所有的 EventEmitter,当添加新的监听器时触发事件 ‘newListener’,当删除现有的监听器时触发事件 ‘removeListener’。
2、事件触发器的方法
在Node.js中,为EventEmitter类定义了许多方法,所有与对象的事件处理函数的绑定及解除相关的处理均依靠这些方法的调用来执行。
常用方法:(event
:代表事件名,listener
:代表事件处理函数)
方法名与参数 | 描述 |
---|---|
addListener(event,listener) | 事件监听函数,emitter.on(eventName, listener) 的别名。 |
on(event, listener) | 对指定对象绑定事件处理函数(addListener方法的别名) |
once(event, listener) | 对指定对象指定只执行一次的事件处理函数 |
removeListener(event, listener) | 删除事件 |
setMaxListeners(n) | 指定对象处理函数的最大数量,n为正数值,代表最大的可指定事件处理函数的数量 |
listeners(event) | 获取指定对象的所有事件处理函数 |
emit(event, [arg1], [arg2], […]) | 手动触发指定事件 |
newListener(event,Listener) | 添加新的监听器 |
(1)EventEmitter类的on方法
emitter.on(eventName, listener);
eventName < string > | < symbol > 事件的名称。
listener < Function > 回调函数
返回: < EventEmitter >
将 listener 函数添加到名为 eventName 的事件的监听器数组的末尾。 不检查是否已添加 listener。 多次调用传入相同的 eventName 和 listener 组合将导致多次添加和调用 listener。默认情况下,事件监听器按添加顺序调用。
例1:当服务器接收到客户端请求时,在控制台窗口中输出客户端请求的目标地址(URL地址),并使用响应对象的end方法立即结束响应。
const http = require('http');
//创建服务器对象
let server = http.createServer();
//给服务器对象绑定事件request
server.on('request',function (req,res){
//输出请求对象的地址
console.log('请求地址:',req.url);
//服务器关闭和客户端的连接,并发送响应信息
res.end('hello world');
})