Node中的事件events

前言


🤡events模块是node中的一个核心模块,常常用来进行处理异步和模块之间的通信,Node中的事件模块简单易用,如果你熟悉Vue,我们知道Vue中模块之间的通信我们会用到eventbus其实Node中的事件模块的使用方式基本上和eventbus一模一样,我们可以把事件看成一种简单的信号就像我们在Vue中对某个数据进行的监听操作一样,当监听的数据发生变化就进行相应的操作~

一.EventEmitter的基本使用


二.添加事件监听


🤡我们使用EventEmitter首先需要从events模块中到处此对象然后调用具体的方法进行使用,从上面的图中我们可以看到基本常用的操作包含几种分别是:添加监听事件,关闭移除事件,事件触发一次等等常用操作~

js 复制代码
const { EventEmitter } = require('events')
const eventEmitter = new EventEmitter()
// 监听事件
eventEmitter.on('data', () => {
  console.log("监听到了data事件~")
})
// 触发data事件
eventEmitter.emit('data')

在Node的事件处理中,不仅仅可以使用on进行监听,并且可以使用addListener来进行监听并且不仅仅可以通过off进行 移除监听还可以通过removeListener来进行关闭移除事件监听,下面就让我们来看下这些API的用法~

js 复制代码
const { EventEmitter } = require('events')
const eventEmitter = new EventEmitter()
// 监听事件
eventEmitter.on('data', () => {
  console.log("监听到了data事件~")
})

eventEmitter.addListener("data", () => {
  console.log("监听到了data事件2~")
})
// 触发data事件
eventEmitter.emit('data')

🦝事件监听器的执行顺序:在Node事件中,监听事件的执行顺序就是代码的书写顺序。

js 复制代码
const {EventEmitter} = require("events");
const eventEmitter = new EventEmitter();

eventEmitter.on("data", () => {
    console.log("data 1");
});

eventEmitter.on("data", () => {
    console.log("data 2");
});

eventEmitter.on("data", () => {
    console.log("data 3");
});

eventEmitter.emit("data");

😊事件监听的重复添加:对同一个事件对象可以进行重复添加,并且不同的监听均可以正常使用。

js 复制代码
const {EventEmitter} = require('events');
const eventEmitter = new EventEmitter();

const listener = () => {
    console.log("lsitener");
}

eventEmitter.on("data", listener);
eventEmitter.on("data", listener);
eventEmitter.emit("data");

😈传递参数:对某个事件进行监听的同时还可以对这个事件进行传递参数

js 复制代码
const {EventEmitter} = require("events");
const eventEmitter = new EventEmitter();

eventEmitter.on("data", data => {
    console.log(data);
});

eventEmitter.emit("data", "东方甄选小作文");

三.关闭移除事件监听


👹移除事件监听同样提供了两个方法,移除事件监听可以使用offremoveListener他的基本使用方式如下

js 复制代码
removeListener(eventName, listener)

并且两个参数都是必传的,因为对某个事件进行监听可能会有多个不同的函数执行逻辑,就像下面这种,可能监听的myEvent事件有两个不同的执行函数逻辑listener1listener2两个函数,所以参数中函数也是必须要传的否则会报错。

js 复制代码
const EventEmitter = require('events');
const myEmitter = new EventEmitter();

const listener1 = () => {
  console.log('监听器1执行');
};

const listener2 = () => {
  console.log('监听器2执行');
};

myEmitter.on('myEvent', listener1);
myEmitter.on('myEvent', listener2);

// 移除特定的监听器
myEmitter.removeListener('myEvent', listener1);

// 触发事件
myEmitter.emit('myEvent');

😀和添加事件一样,移除事件监听也可以使用off这个方式,使用方法和removeListener使用方式一样,按照上方的代码将removeListener更改为off即可

💡Tips:如果我们使用 on 或者 addListener 绑定的是一个匿名函数,那么便无法通过 off 和 removeListener 去解绑一个回调函数,因为它会通过比较两个函数的引用是否相同来解绑函数的。

🐻removeAllListener:removeAllListenerAPI也是用来移除监听的,但是这个removeAllListener是用来直接移除当前事件对象监听的所有内容,直接将事件对象传入即可移除这个事件对象上绑定的所有内容,使用方式如下

js 复制代码
const {EventEmitter} = require('events');
const eventEmitter = new EventEmitter();

eventEmitter.on("data", () => {
    console.log("data 1");
});

eventEmitter.on("data", () => {
    console.log("data 2");
});

eventEmitter.emit("data");
eventEmitter.removeAllListeners("data");
eventEmitter.emit("data");

四.事件单次触发once


🥺有时候我们并不需要每次点击都需要触发,在某些需求情况下,我们可能只需要触发一次对应的事件,当触发过后就对这个事件进行解绑,在Node中提供了这样的API来仅仅触发一次。

js 复制代码
const {EventEmitter} = require("events");
const eventEmitter = new EventEmitter();

eventEmitter.once("data", () => {
    console.log("data");
});

eventEmitter.emit("data"); // 触发了
eventEmitter.emit("data"); // 没有触发

五.prependList相关API


🦝当我们使用onceon等API来进行事件监听的代码编写,其中的回调函数的执行会按照代码的编写顺序来执行,但是当我们想添加一个事件让在其他回调函数之前执行的话我们第一时间想到的事情就是把这个事件放在所有的事件API的最上边,但是这样做有很多问题存在,也不利于代码的维护,所以Node提供了prependList相关的API,这样绑定的事件回调函数会在其他回调函数之前执行。

js 复制代码
const {EventEmitter} = require('events');
const eventEmitter = new EventEmitter();

eventEmitter.on("data", () => {
    console.log("on");
});

eventEmitter.prependListener("data", () => {
    console.log("prepend");
});

eventEmitter.emit("data");

🤡当然如果像其他API一样仅仅想执行一次也可以使用prependOnceListener来进行监听。

js 复制代码
const {EventEmitter} = require('events');
const eventEmitter = new EventEmitter();

eventEmitter.on("data", () => {
    console.log("on");
});

eventEmitter.prependOnceListener("data", () => {
    console.log("prepend once");
});

eventEmitter.emit("data");
eventEmitter.emit("data");

六.其他常用API


😈如果在开发中我们使用了事件对象监听了很多事件,并且事件名称也有很多,我们想看下都监听了哪些事件,我们该如何查看,🥺不会要一个一个的查看吧? 那脑袋岂不裂开了,你遇到的问题同样是Node官方考虑过的问题,Node提供了eventNames通过事件对象直接调用这个方法来查看,事件对象上都绑定了哪些事件,事件会以数组的方式进行展示。

js 复制代码
const {EventEmitter} = require("events");
const eventEmitter = new EventEmitter();

eventEmitter.on("start", () => {
    console.log("start");
});
eventEmitter.on("end", () => {
    console.log("end");
});
eventEmitter.on("error", () => {
    console.log("error");
});

console.log(eventEmitter.eventNames()); // [ 'start', 'end', 'error' ]

✅既然可以获取不同监听事件的名称,那么可以获取事件对象绑定的素有回调函数吗?当然也是可以的我们可以通过listenerCount来查看绑定回调函数的多少

js 复制代码
const {EventEmitter} = require("events");
const eventEmitter = new EventEmitter();

eventEmitter.on("data", () => {

});
eventEmitter.on("data", () => {

});

console.log(eventEmitter.listenerCount("data")); // 2

👹在Node中其实绑定回调函数的数量是被限制的,一般默认最多绑定10个,我们可以通过EventEmitter.defaultMaxListeners来获取绑定的默认数量,但是当我们有绑定更多个或者对数量进行限制的时候我们需要进行具体的修改,修改绑定数量和获取绑定数量的API为setMaxLsitenersgetMaxListeners具体使用方式如下

js 复制代码
const {EventEmitter} = require("events");
const eventEmitter = new EventEmitter();

eventEmitter.setMaxListeners(1);

console.log(eventEmitter.getMaxListeners()); // 1

😀不对呀!通过listenerCount只是获取到的回调函数的数量,不是获取回调函数组成的列表!别着急,获取函数列表也有指定的API,当然我们的目的不仅仅是记忆API而已找到规律一次性搞定,就算很多API没用过我们看下也可以很快的上手。

🐫在Node中获取事件绑定回调函数的列表通过以下两个API来获取listenersrawListeners

js 复制代码
const {EventEmitter} = require("events");
const eventEmitter = new EventEmitter();

eventEmitter.once("data", () => {
    console.log("once");
})

let fn = eventEmitter.listeners("data");
fn[0]()
eventEmitter.emit("data");
js 复制代码
const {EventEmitter} = require("events");
const eventEmitter = new EventEmitter();

eventEmitter.once("data", () => {
    console.log("once");
})
let fn = eventEmitter.rawListeners("data");
fn[0]()
eventEmitter.emit("data");

listenersrawListeners的区别简而言之就是一个返回的函数是处理后的,一个是原来的,使用上注意区分once情况下的不同即可,以下是比较完整的回答~

  1. listeners方法返回一个包含指定事件的监听器函数列表的数组。这些监听器函数是经过封装的rawListeners与 listeners 不同的是,对于 once 绑定的回调函数返回的是 wrapper,而不是原生绑定的函数。
  2. rawListeners(eventName)方法与listeners()方法类似,也返回一个包含指定事件的监听器函数列表的数组。但与listeners()方法不同的是,rawListeners()方法返回的数组包含了原始的监听器函数,而不是包装后的监听器函数。
  3. rawListeners()方法返回的监听器函数是未经过封装的原始函数,通常用于内部调试或高级使用场景。你可以直接访问和操作这些原始监听器函数,而不会影响到其他地方监听同一事件的监听器函数。

七.总结


✅events模块是Node中一个比较重要的模块,我们经常用来进行模块间消息通知的时候使用,events有很多常见的API用来做不同的事情,API使用的方法大致相同,重要需要注意不同的地方的使用差别,关于events模块还有其他API,但是这些比较常用,其他用到的用的时候去查就可以了,events模块这篇文章就到这了,这样一点一点的学习,相信在不久的将来你一当会为一名Node的高手,加油吧~

相关推荐
Estar.Lee4 小时前
查手机号归属地免费API接口教程
android·网络·后端·网络协议·tcp/ip·oneapi
2401_857610035 小时前
SpringBoot社团管理:安全与维护
spring boot·后端·安全
凌冰_6 小时前
IDEA2023 SpringBoot整合MyBatis(三)
spring boot·后端·mybatis
码农飞飞6 小时前
深入理解Rust的模式匹配
开发语言·后端·rust·模式匹配·解构·结构体和枚举
一个小坑货6 小时前
Rust 的简介
开发语言·后端·rust
monkey_meng6 小时前
【遵守孤儿规则的External trait pattern】
开发语言·后端·rust
Estar.Lee7 小时前
时间操作[计算时间差]免费API接口教程
android·网络·后端·网络协议·tcp/ip
新知图书7 小时前
Rust编程与项目实战-模块std::thread(之一)
开发语言·后端·rust
盛夏绽放8 小时前
Node.js 和 Socket.IO 实现实时通信
前端·后端·websocket·node.js
Ares-Wang8 小时前
Asp.net Core Hosted Service(托管服务) Timer (定时任务)
后端·asp.net