当前位置:首页 > 技术分析 > 正文内容

好好了解一下 EventEmitter(好好了解一下怎么回)

ruisui8810小时前技术分析1

在 JavaScript 中,EventEmitter 是一个事件驱动编程的核心工具,用于实现对象间的发布-订阅(Pub/Sub)模式。它允许对象监听和触发自定义事件,常用于异步通信、模块解耦等场景。

1. EventEmitter 的核心概念

  • 事件(Event):一个标识符(如 'message' 或 'error'),表示某种行为或状态变化。
  • 监听器(Listener):绑定到事件的回调函数,当事件触发时执行。
  • 触发(Emit):主动调用某个事件,执行所有绑定的监听器。

2. 原生 EventEmitter 的使用

在 Node.js 中,EventEmitterevents 模块的内置类。浏览器环境无原生支持,但可手动实现或使用第三方库(如 EventTarget)。

Node.js 示例


const EventEmitter = require('events');


// 创建实例

class MyEmitter extends EventEmitter {}

const emitter = new MyEmitter();


// 监听事件

emitter.on('message', (data) => {

console.log('收到消息:', data);

});


// 触发事件

emitter.emit('message', 'Hello World!'); // 输出: 收到消息: Hello World!


3. 浏览器的替代方案

(1) 使用 EventTarget(浏览器原生 API)


const eventTarget = new EventTarget();


// 监听事件

eventTarget.addEventListener('click', (e) => {

console.log('事件数据:', e.detail);

});


// 触发自定义事件

const event = new CustomEvent('click', {

detail: { x: 100, y: 200 } // 可携带数据

});

eventTarget.dispatchEvent(event);


(2) 手动实现简单 EventEmitter


class EventEmitter {

constructor() {

this.events = {}; // 存储事件及监听器

}


// 监听事件

on(eventName, listener) {

if (!this.events[eventName]) {

this.events[eventName] = [];

}

this.events[eventName].push(listener);

}


// 触发事件

emit(eventName, ...args) {

const listeners = this.events[eventName];

if (listeners) {

listeners.forEach(listener => listener(...args));

}

}


// 移除监听器

off(eventName, listenerToRemove) {

const listeners = this.events[eventName];

if (listeners) {

this.events[eventName] = listeners.filter(

listener => listener !== listenerToRemove

);

}

}

}


// 使用示例

const emitter = new EventEmitter();

emitter.on('log', (message) => {

console.log('日志:', message);

});

emitter.emit('log', '用户登录'); // 输出: 日志: 用户登录


4. EventEmitter 的关键方法

方法

作用

.on(event, listener)

绑定事件监听器

.once(event, listener)

绑定一次性监听器(触发后自动移除)

.emit(event, [...args])

触发事件,并传递参数

.off(event, listener)

移除指定事件的某个监听器

.removeAllListeners()

移除所有监听器

5. 在前端代码中的用途

在之前的 WebRTC 示例中,EventEmitter 被用作信令通道的模拟,实际项目中需替换为真正的网络通信(如 WebSocket):


// 示例中的模拟信令通道

const signaling = new EventEmitter();


// 发送 Offer(模拟网络传输)

signaling.emit('offer', offerDescription);


// 接收 Answer(模拟网络接收)

signaling.on('answer', (answer) => {

pc.setRemoteDescription(answer);

});


6. 注意事项

内存泄漏
不使用的监听器需通过
.off() 主动移除,否则可能因对象无法回收导致内存泄漏。

异步触发
监听器的执行是同步的,若需异步操作,需自行封装(如用
setTimeoutPromise)。

错误处理
建议始终监听
'error' 事件,避免未捕获的异常导致进程崩溃(Node.js 中尤为重要):


emitter.on('error', (err) => {

console.error('发生错误:', err);

});


7. 常见应用场景

  • UI 组件通信:父子组件间传递数据(如 Vue/React 中的事件总线)。
  • 网络通信:封装 WebSocket 消息的发布-订阅。
  • 状态管理:Redux 或 Vuex 中响应状态变化。
  • 异步任务协调:多个异步操作完成后触发事件。

总结一下

EventEmitter 是 JavaScript 事件驱动编程的基石,无论是 Node.js 后端还是前端复杂交互,它都能通过解耦代码逻辑提升可维护性。实际开发中,可根据场景选择原生 API、手动实现或第三方库(如 mittEventEmitter3)。

爱学习小伙伴更多精彩关注不迷路哟~

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/3800.html

分享给朋友:

“好好了解一下 EventEmitter(好好了解一下怎么回)” 的相关文章

首个支持苹果 M1 Mac 的 Linux 发行版发布,面向用户开放下载

IT之家 3 月 20 日消息,Asahi Linux 是研究 Linux for Apple Silicon macs 的组织群体,3 月 18 日,Asahi Linux 宣布成功在 M1 MacBook Air 笔记本电脑上运行,并开放了 Asahi Linux 的下载安装。Asahi Lin...

带你五步学会Vue SSR

作者:liuxuan 前端名狮转发链接:https://mp.weixin.qq.com/s/6K6GUHcLwLG4mzfaYtVMBQ前言SSR大家肯定都不陌生,通过服务端渲染,可以优化SEO抓取,提升首页加载速度等,我在学习SSR的时候,看过很多文章,有些对我有很大的启发作用,有些就只是照搬官...

30 个纯 HTML5 实现的游戏

浏览器和 JavaScript 的功能逐年不断的变强变大。曾几何时,任何类型的游戏都需要Flash。但随着 HTML5 发展,HTML5 + WebGL 游戏式就慢慢占领着这个舞台。以下是30款流行的游戏,它们可以在所有现代浏览器中运行,并且只使用web技术构建。1. HexGL地址:http://...

双子座应用程序推出模型切换器以在Android上访问2.0

#头条精品计划# 快速导读谷歌推出了Gemini 2.0 Flash实验版,现已在其安卓应用中可用,之前仅在gemini.google.com网站上提供。新版本的15.50包含模型切换器,用户可以在设置中选择不同模型,包括1.5 Pro、1.5 Flash和2.0 Flash实验版。谷歌提醒,2.0...

虚幻引擎5.5发布

IT之家 11 月 13 日消息,虚幻引擎 5.5 现已发布。据介绍,新版本虚幻引擎在动画创作、虚拟制作和移动游戏开发方面取得进步;渲染、摄像机内视觉特效和开发人员迭代等领域的部分功能已可用于生产。IT之家整理部分功能亮点如下:动画Sequencer增强虚幻引擎的非线性动画编辑器 Sequencer...

js中数组filter方法的使用和实现

定义filter() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。语法var newArray = arr.filter(callback(element[, index[, selfArr]])[, thisArg])参数callback循环数组每个元素时调用的回调函数。回调函...