【Node】【4】事件循环和EventEmitter类

事件循环

事件驱动: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 模块创建事件和事件处理程序。当事件被触发时,相关的事件处理程序会被执行。以下是代码的执行流程:

  1. 首先,创建了一个 EventEmitter 实例 eventEmitter,它用于处理事件的注册、触发和监听。
  2. 定义了一个名为 connectHandler 的事件处理程序,它会在 connection 事件被触发时输出 连接成功。 并且触发 data_received 事件。
  3. connectHandler 事件处理程序绑定到 connection 事件上,这样当 connection 事件被触发时,connectHandler 会被执行。
  4. 使用匿名函数绑定了 data_received 事件,该函数在 data_received 事件被触发时输出 数据接收成功。
  5. 触发了 connection 事件,这会导致 connectHandler 被执行,输出 连接成功。 并触发 data_received 事件。
  6. data_received 事件被触发时,匿名函数会被执行,输出 数据接收成功。
  7. 最后,输出 程序执行完毕。

在这里插入图片描述

事件处理是异步的。当触发 connection 事件时,Node.js 将 connectHandlerdata_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');

  • 11
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凭栏听雨客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值