【第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 事件。从运行结果可以发现两个事件监听器回调函数被先后调用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/186236.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LabVIEW如何才能得到共享变量的引用

LabVIEW如何才能得到共享变量的引用 有一个LabVIEW 库文件 (.lvlib) ,其中有一些定义好的共享变量。但需要得到每个共享变量的引用以便在程序运行时访问其属性。 共享变量的属性定义在“变量”类属性节点中。为了访问变量类,共享变量的引用必须连接到变…

Leetcode Hot 100之四:283. 移动零+11. 盛最多水的容器

283.移动零 题目: 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 请注意 ,必须在不复制数组的情况下原地对数组进行操作。 示例 1: 输入: nums [0,1,0,3,12] 输出: [1,3,12,0,0] …

数据结构与算法—双链表

前言 前面有很详细的讲过线性表(顺序表和链表),当时讲的链表以单链表为主,但在实际应用中双链表有很多应用场景,例如大家熟知的LinkedList。 双链表与单链表区别 单链表和双链表都是线性表的链式实现,它们的主要区别在于节点结构…

048-第三代软件开发-数据回放

第三代软件开发-数据回放 文章目录 第三代软件开发-数据回放项目介绍数据回放 关键字: Qt、 Qml、 Data、 play back、 数据 项目介绍 欢迎来到我们的 QML & C 项目!这个项目结合了 QML(Qt Meta-Object Language)和 C 的…

【C++】单例模式【两种实现方式】

目录 一、了解单例模式前的基础题 1、设计一个类,不能被拷贝 2、设计一个类,只能在堆上创建对象 3、设计一个类,只能在栈上创建对象 4、设计一个类,不能被继承 二、单例模式 1、单例模式的概念 2、单例模式的两种实现方式 …

Qt工程打包工具 windeployqt 的用法

1.复制工程下的“Debug”或者“Release”文件夹到你喜欢的路径,例如:D:\QT_out\ 2.在操作系统“开始”选项找到“Qt”文件夹,打开“Qt 5.15.2(MSVC 2019 64-bit)” 重点: 这里要注意的是,一定…

Linux常见指令:从基础到理论

前言 目录 前言 1. find指令 拓展 2. grep指令 拓展 sort指令 uniq指令 wc指令 3. zip/unzip指令 4. tar指令 5. uname指令 拓展 6. Linux常用热键 7. 关机 8. rz指令 拓展 scp指令 9. shell命令以及运行原理 Linux常见指令是使用Linux系统时必不可少的一部分。通过掌握…

简单好看个人引导页毛玻璃页面 HTML 源码

毛玻璃个人引导页源码,界面简洁,已测可完美搭建,UI非常不错的,有兴趣的自行去安装体验吧,其它就没什么好介绍的了。 学习资料源代码:百度网盘 请输入提取码:ig8c

[RCTF 2019]nextphp

文章目录 考点前置知识PHP RFC:预加载FFI基本用法PHP RFC:新的自定义对象序列化机制 解题过程 考点 PHP伪协议、反序列化、FFI 前置知识 PHP RFC:预加载 官方文档 通过查看该文档,在最下面找到预加载结合FFI的危害 FFI基本用法 …

Selenium关于内容信息的获取读取

在进行自然语言处理、文本分类聚类、推荐系统、舆情分析等研究中,通常需要使用新浪微博的数据作为语料,这篇文章主要介绍如果使用Python和Selenium爬取自定义新浪微博语料。因为网上完整的语料比较少,而使用Selenium方法有点简单、速度也比较慢,但方法可行,同时能够输入验…

yolov5 通过视频进行目标检测

打开yolov5-master文件夹,可以看到一个名为data的文件夹,在data中创建一个新的文件夹,命名为videos。 打开yolov5-master中的detect.py可以看到一行代码(大概在245行左右)为 parser.add_argument(--source, typestr,…

fastspar微生物相关性推断

fastspar 简介 fastspar是基于Sparcc通过C编写的,速度更快,内存消耗更少。sparcc是基于OTU的原始count数,通过log转换和标准化去除传统相对丰度的天然负相关(因为所有OTU之和为1,某些OTU丰度高另外一些自然就少&…

tqdm学习

from tqdm import tqdmepochs 10 epoch_bar tqdm(range(epochs)) count 0 for _ in epoch_bar:count count1print("count {}".format(count))print(_)每次就是一个epoch

【Python】数据分析案例:世界杯数据可视化

文章目录 前期数据准备导入数据 分析:世界杯中各队赢得的比赛数分析:先打或后打的比赛获胜次数分析:世界杯中的抛硬币决策分析:2022年T20世界杯的最高得分者分析:世界杯比赛最佳球员奖分析:最适合先击球或追…

JAVA代码视频转GIF(亲测有效)

1.说明 本次使用的是JAVA代码视频转GIF&#xff0c;maven如下&#xff1a; <dependency><groupId>ws.schild</groupId><artifactId>jave-nativebin-win64</artifactId><version>3.2.0</version></dependency><dependency&…

07、SpringBoot+微信支付 -->处理超时订单(定时查询、核实微信支付平台的订单、调用微信支付平台查单接口、更新本地订单状态、记录支付日志)

目录 Native 支付处理超时订单定时的讲解需求分析代码定时任务&#xff1a;WxPayTask定时查询的方法&#xff1a;核实订单状态等操作 &#xff1a;WxPayServiceImpl查单接口方法&#xff1a;queryOrder更新本地订单状态&#xff1a;updateStatusByOrderNo记录支付日志&#xff…

苍穹外卖-day06

苍穹外卖-day06 课程内容 HttpClient微信小程序开发微信登录导入商品浏览功能代码 功能实现&#xff1a;微信登录、商品浏览 微信登录效果图&#xff1a; 商品浏览效果图&#xff1a; 1. HttpClient 1.1 介绍 HttpClient 是Apache Jakarta Common 下的子项目&#xff0c;…

单例模式 rust和java的实现

文章目录 单例模式介绍应用实例&#xff1a;优点使用场景 架构图JAVA 实现单例模式的几种实现方式 rust实现 rust代码仓库 单例模式 单例模式&#xff08;Singleton Pattern&#xff09;是最简单的设计模式之一。这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建…

rabbitMQ rascal/amqplib报错 Error: Unexpected close 排查

以下是一些可能导致此 RabbitMQ 客户端或任何其他 RabbitMQ 客户端中的套接字读取或写入失败的常见场景 1.错过&#xff08;客户端&#xff09;心跳 第一个常见原因是RabbitMQ 检测到心跳丢失。发生这种情况时&#xff0c;RabbitMQ 将添加一个有关它的日志条目&#xff0c;然…

SQL note1:Basic Queries + Joins Subqueries

目录 一、Basic Queries 1、数据库术语 2、查表 3、过滤掉我们不感兴趣的行 4、布尔运算 5、过滤空值&#xff08;NULL&#xff09; 6、分组和聚合 1&#xff09;汇总数据的列 2&#xff09;汇总数据组 7、分组聚合的警告 1&#xff09;SELECT age, AVG(num_dogs) FR…