当前位置: 首页 > news >正文

【第2章 Node.js基础】2.3 Node.js事件机制

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会触发相应的事件,并将事件传递给注册的事件处理函数。

在这里插入图片描述

  1. 事件循环的六个阶段:事件循环包括六个阶段,分别是:timers(定时器),pending callbacks(待处理的回调),idle, prepare(空闲和准备),poll(轮询),check(检查),close callbacks(关闭回调)。

  2. 进入阶段并执行操作:事件循环进入某个阶段时,会执行该阶段特有的操作。例如,在timers阶段会执行定时器的回调函数,而在poll阶段会处理I/O事件等。

  3. 执行回调函数队列:在每个阶段中,事件循环会维持一个先进先出的可执行回调函数队列。事件循环会依次执行队列中的回调函数,直到队列结束或达到回调限制数。

  4. 切换到下一个阶段:当队列结束或达到回调限制数时,事件循环会切换到下一个阶段继续处理。这样循环进行,直到所有阶段都执行完毕。

  5. 检查非阻塞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 事件。从运行结果可以发现两个事件监听器回调函数被先后调用。

相关文章:

  • 【数学】Pair of Topics—CF1324D
  • Android各类View触摸监听器失效
  • 【GitHub】PR的学习笔记
  • bin、hex、ELF文件格式上的区别
  • Spring 常见面试题
  • 基于JavaWeb+SpringBoot+Vue摩托车商城微信小程序系统的设计和实现
  • STM32——NVIC中断优先级管理分析
  • springcloud旅游网站源码
  • 使用LLM-Tuning实现百川和清华ChatGLM的Lora微调
  • C_7练习题
  • 【计算机网络】UDP协议
  • JavaWeb篇_09——Tomcat运行过程以及Servlet继承结构
  • 用Go实现yaml文件节点动态解析
  • uni-app学习笔记(二)
  • Redis模块的高级使用方式
  • hexo+github搭建个人博客
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • 【挥舞JS】JS实现继承,封装一个extends方法
  • 2017-08-04 前端日报
  • CSS进阶篇--用CSS开启硬件加速来提高网站性能
  • javascript从右向左截取指定位数字符的3种方法
  • k8s如何管理Pod
  • laravel 用artisan创建自己的模板
  • SAP云平台里Global Account和Sub Account的关系
  • 从零开始在ubuntu上搭建node开发环境
  • 给github项目添加CI badge
  • 关于Android中设置闹钟的相对比较完善的解决方案
  • 基于Vue2全家桶的移动端AppDEMO实现
  • 蓝海存储开关机注意事项总结
  • 前端攻城师
  • 驱动程序原理
  • 实战:基于Spring Boot快速开发RESTful风格API接口
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 项目管理碎碎念系列之一:干系人管理
  • 自定义函数
  • 3月7日云栖精选夜读 | RSA 2019安全大会:企业资产管理成行业新风向标,云上安全占绝对优势 ...
  • 阿里云服务器如何修改远程端口?
  • 摩拜创始人胡玮炜也彻底离开了,共享单车行业还有未来吗? ...
  • ​2021半年盘点,不想你错过的重磅新书
  • #我与Java虚拟机的故事#连载11: JVM学习之路
  • (pytorch进阶之路)扩散概率模型
  • (二)Linux——Linux常用指令
  • (附源码)php投票系统 毕业设计 121500
  • (附源码)springboot教学评价 毕业设计 641310
  • (切换多语言)vantUI+vue-i18n进行国际化配置及新增没有的语言包
  • (四)鸿鹄云架构一服务注册中心
  • (原創) 人會胖會瘦,都是自我要求的結果 (日記)
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • (转)Unity3DUnity3D在android下调试
  • (转)用.Net的File控件上传文件的解决方案
  • .axf 转化 .bin文件 的方法
  • .bashrc在哪里,alias妙用
  • .cfg\.dat\.mak(持续补充)
  • .NET Compact Framework 多线程环境下的UI异步刷新
  • .NET Core 2.1路线图