js实现简单的【发布者-订阅者模式】

发布订阅模式是什么

发布订阅模式是一种代码的设计模式,它允许对象间进行松散耦合的通信。
发布者(Publishers)不会直接调用订阅者(Subscribers),相反,它们通过事件通道发布消息;订阅者通过注册监听事件通道上的消息来做出响应。
这种模式在事件驱动编程和异步编程中非常有用。

发布订阅模式怎么实现

发布订阅模式在前端开发中有广泛的应用。例如,事件处理、状态管理库(如 Redux)、消息中间件、数据流控制等

1)一个用于存储事件及其对应回调的事件中心。

2)一个 on 方法,用于订阅某个事件,并将回调函数注册到事件中心中。

3)一个 emit 方法,用于发布某个事件,并调用所有订阅该事件的回调函数。

4)一个 off 方法,用于解除订阅。

使用场景:
发布-订阅模式可用于解耦复杂的代码逻辑,例如:
浏览器中的事件处理(如点击,输入等);
背景任务和前台任务之间的通信;
多模块或组件之间的通信。

高级实现:
在实际开发中,我们可能会用到一些更复杂的发布-订阅库比如 EventEmitter (Node.js 内置)、PubSubJS 等,这些库提供了更具备鲁棒性的实现和更多特性。

代码

let eventEmitter ={//事件中心events:{},//订阅事件on: function (eventName,callback){//如果事件不存在if(!this.events[eventName]){this.events[eventName] = [];}this.events[eventName].push(callback);},//发布事件 事件触发emit:function (eventName,...args){// 事件不存在if(!this.events[eventName]){return ;}this.events[eventName].forEach(callback =>{callback(...args)})},//取消事件off:function (eventName,callback){if(this.events[eventName]){this.events[eventName] = this.events[eventName].filter(e=>e!==callback)}},/*** 这里的 args 并没有在 once 函数的参数列表中明确声明,* 而是作为 onceWrapper 函数的一个内部变量(通过剩余参数语法捕获)。* 这是因为 onceWrapper 函数不知道它会接收多少个参数,* 所以它使用 ...args 来捕获所有参数,并将它们作为一个数组处理* 。然后,它可以通过 callback(...args) 将这些参数传递给 callback 函数*///一次性订阅once:function (eventName,callback){const onceWrapper = (...args)=>{callback(...args)//执行一次后取消订阅this.off(eventName,onceWrapper)}this.on(eventName,onceWrapper)}}//示例
//用户定义的回调函数
function user1(msg){console.log("user1 ",msg);
}function user2(msg){console.log("user2 ",msg);
}function user3(msg){console.log("user3 ",msg);}
//注册事件
eventEmitter.on("test",user1)
eventEmitter.on("test",user2)//事件触发
eventEmitter.emit("test","这是一个测试")//取消订阅
eventEmitter.off('test', user1);// 发布
eventEmitter.emit('test', '这次只有 User2 收到消息');//一次性订阅注册
eventEmitter.once("once",user3)//事件触发两次
eventEmitter.emit("once","test by user3")
eventEmitter.emit("once","test by user3")//没有输出

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

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

相关文章

【ELK】初始阶段

一、logstash学习 安装的时候最好不要有中文的安装路径 使用相对路径 在 Windows PowerShell 中,如果 logstash 可执行文件位于当前目录下,你需要使用相对路径来运行它。尝试输入以下命令: .\logstash -e ‘input { stdin { } } output { s…

Ubuntu22.04 制作系统ISO镜像

第一步:安装软件-Systemback 1.如果已经添加过ppa,可以删除重新添加或者跳过此步 sudo add-apt-repository --remove ppa:nemh/systemback 2.添加ppa 我是ubuntu20,但这个软件最后支持的是 ubuntu16.04版本,所以加一个16版本…

通过Python爬虫获取商品销量数据,轻松掌握市场动态

为什么选择Python爬虫? 简洁易用:Python语言具有简洁的语法和丰富的库,使得编写爬虫变得简单高效。强大的库支持:Python拥有强大的爬虫框架(如Scrapy、BeautifulSoup、Requests等),可以快速实现…

算法1—八大常用排序算法(上)

1.直接插入排序 原理:从arr[0]开始,每次和后一个数据比大小,然后根据需要的是升序还是降序进行操作。 最差的情况下时间复杂度:O(n) 最好的情况下时间复杂度:O(1) 所…

漏洞挖掘 | 通过域混淆绕过实现账户接管

由于这是一个私有项目,我将使用 example.com 来代替。 很长一段时间以来,我一直想在漏洞赏金项目中找到一个账户接管(ATO)漏洞。于是,我开始探索项目范围内的 account.example.com。 我做的第一件事就是注册一个新账…

WebRTC音频 03 - 实时通信框架

WebRTC音频01 - 设备管理 WebRTC音频 02 - Windows平台设备管理 WebRTC音频 03 - 实时通信框架(本文) WebRTC音频 04 - 关键类 WebRTC音频 05 - 音频采集编码 一、前言: 前面介绍了音频设备管理,并且以windows平台为例子,介绍了ADM相关的类…

探索 Web Audio API 的奇妙世界

Web Audio API 是一项强大而灵活的 JavaScript API,它允许开发者在网页中处理和生成音频。本文将带您深入了解 Web Audio API 的基本概念,并介绍一些令人兴奋的应用场景。 1. 什么是 Web Audio API? Web Audio API 是一组用于处理和生成音频…

react18中在列表项中如何使用useRef来获取每项的dom对象

在react中获取dom节点都知道用ref,但是在一个列表循环中,这样做是行不通的,需要做进一步的数据处理。 实现效果 需求:点击每张图片,当前图片出现在可视区域。 代码实现 .box{border: 1px solid #000;list-style: …

计算机专业大学四年的学习路线(非常详细),零基础入门到精通,看这一篇就够了

前言 许多学子选择踏上计算机这条充满挑战与机遇的道路。但在大学四年中,如何规划自己的学习路线,才能在毕业时脱颖而出,成为行业的佼佼者呢? 第一学年:基础知识的奠基 1.1 课程安排 在大学的第一年,重…

elementUI进度条el-progress不显示白色

效果图 通过设置百分比为100,动态修改进度条的宽度完成 <template><div class"myProgressBox"><div class"index">{{ index }}</div><div class"typeTitle">{{ typeTitle }}</div><div class"twoP…

【UE5】将2D切片图渲染为体积纹理,最终实现使用RT实时绘制体积纹理【第六篇-阶段总结篇】

因为马上就要进入下一个阶段&#xff0c;制作动态编辑体积纹理的模块。 但在这之前&#xff0c;要在这一章做最后一些整理。 首先&#xff0c;我们完成没完成的部分。其次&#xff0c;最后整理一下图表。最后&#xff0c;本文附上正在用的贴图 完善Shader 还记得我们之前注…

『完整代码』坐骑召唤

创建一个按钮 作为召唤/消失坐骑的开关 将预制体放入指定文件夹 命名为Mount01 创建脚本并编写&#xff1a;CallMount.cs using UnityEngine; using UnityEngine.UI; public class CallMount : MonoBehaviour{public Button callBtn;GameObject mountPrefab;GameObject mountIn…

嵌套div导致子区域margin失效问题解决

嵌套div导致子区域margin失效问题解决 现象原因解决方法 现象 <div class"prev"></div> <div class"parent"><div class"child"></div><div class"child"></div> </div> <div cl…

Netty无锁化设计之对象池实现

池化技术是比较常见的一种技术&#xff0c;在平时我们已经就接触很多了&#xff0c;比如线程池&#xff0c;数据库连接池等等。当我们要使用一个资源的时候从池中去获取&#xff0c;用完就放回池中以便其他线程可以使用&#xff0c;这样的目的就是为了减少资源开销&#xff0c;…

MySQL-23.多表查询-内连接

一.内连接 -- 多表查询 select * from tb_emp,tb_dept where tb_emp.dept_id tb_dept.id;-- 内连接 -- A.查询员工的姓名&#xff0c;及所属的部门名称&#xff08;隐式内连接实现&#xff09; select tb_emp.name as 员工姓名,tb_dept.name as 部门名称 from tb_emp,tb_dep…

简单介绍冯诺依曼体系

现代的计算机, 大多遵守冯诺依曼体系结构 CPU中央处理器&#xff1a;进行算术运算和逻辑判断。存储器&#xff1a;分为外存和内存&#xff0c;用于存储数据&#xff08;使用二进制方式存储&#xff09;。输入设备&#xff1a;用户给计算机发号施令。输出设备&#xff1a;计算机…

RISC-V笔记——Pipeline依赖

1. 前言 RISC-V的RVWMO模型主要包含了preserved program order、load value axiom、atomicity axiom、progress axiom和I/O Ordering。今天主要记录下preserved program order(保留程序顺序)中的Pipeline Dependencies(Pipeline依赖)。 2. Pipeline依赖 Pipeline依赖指的是&a…

LeetCode_2520. 统计能整除数字的位数_java

1、题目 2520. 统计能整除数字的位数https://leetcode.cn/problems/count-the-digits-that-divide-a-number/ 给你一个整数 num &#xff0c;返回 num 中能整除 num 的数位的数目。 如果满足 nums % val 0 &#xff0c;则认为整数 val 可以整除 nums 。 示例 1&#xff1a;…

TiDB替换Starrocks:业务综合宽表迁移的性能评估与降本增效决策

作者&#xff1a; 我是人间不清醒 原文来源&#xff1a; https://tidb.net/blog/6638f594 1、 场景 业务综合宽表是报表生成、大屏幕展示和数据计算处理的核心数据结构。目前&#xff0c;这些宽表存储在Starrocks系统中&#xff0c;但该系统存在显著的性能瓶颈。例如&#…

如何实现金蝶商品数据集成到电商系统的SKU

如何实现金蝶商品数据集成到电商SKU系统 金蝶商品数据集成到电商SKU的技术实现 在现代企业的数据管理中&#xff0c;系统间的数据对接与集成是提升业务效率和准确性的关键环节。本文将分享一个实际案例&#xff1a;如何通过轻易云数据集成平台&#xff0c;将金蝶云星辰V2中的商…