请手写一个发布-订阅的模式

发布-订阅模式也是经典的设计模式之一,它在前端很多地方都有应用,比如javascript事件池Vue的$on、$offnodejs的events模块和socket通信等等都有应用,也是前端面试比较火热的考点之一,接下来给大家详细介绍下发布-订阅模式

发布-订阅模式定义了对象间的一种一对多的依赖关系当一个对象的状态发生变化时,所有依赖它的对象都将得到通知。在JavaScript开发中,我们一般用事件模型来替代传统的发布-订阅模式

要手写一个简单的发布订阅模式,其实现思路如下:

  1. 先初始化一个events对象
  2. 调用on方法时,将事件名称eventName和监听函数fn存入events对象
  3. 调用emit方法时,通过事件名称eventNameevents对象中取出对应的回调并执行
  4. off方法:通过事件名称eventName找出events对象对应的监听函数并清除
  5. once方法:被emit触发一次后就立即调用off方法移除监听,也就是调用once传入的监听函数只会执行一次

代码不多,所以直接上完整代码

class EventEmitter {constructor() {this.events = {}}on(eventName, fn) {if (!this.events[eventName]) {this.events[eventName] = []}this.events[eventName].push(fn)return this}once(eventName, fn) {const func = (...args) => {this.off(eventName, func)fn.apply(this, args)}this.on(eventName, func)return this}emit(eventName, ...args) {if (!this.events[eventName]) return thisthis.events[eventName].forEach(fn => {fn.apply(this, args)});return this}off(eventName, fn) {if (!this.events[eventName]) return thisif (typeof fn === 'function') {this.events[eventName] = this.events[eventName].filter((f) => f !== fn)return this}this.events[eventName] = nullreturn this}
}

const events = new EventEmitter();events.on('event1', () => {console.log('event1', '第一个监听函数')
})
events.on('event1', () => {console.log('event1', '第二个监听函数')
})
events.emit('event1')const fn1 = () => {console.log('event2', '第一个监听函数')
}
const fn2 = () => {console.log('event2', '第二个监听函数')
}
events.on('event2', fn1)
events.on('event2', fn2)
events.off('event2', fn1);// 打印结果:
// event1 第一个监听函数
// event1 第二个监听函数// 上面代码有疑问请阅读下面代码,这部分解答了上面读者的疑问
const events = new EventEmitter();// event1部分
events.on('event1', () => {console.log('event1', '第一个监听函数')
})
events.on('event1', () => {console.log('event1', '第二个监听函数')
})
events.emit('event1')// event2部分
const fn1 = () => {console.log('event2', '第一个监听函数')
}
const fn2 = () => {console.log('event2', '第二个监听函数')
}
events.on('event2', fn1)
events.off('event2', fn1);
events.on('event2', fn2)
events.emit('event2')

  • 可以广泛应用于异步编程中,这是一种替代传递回调函数的方案;
  • 可以取代对象之间硬编码的通知机制,一个对象不用再显示地调用一个对象的接口

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

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

相关文章

cefsharp119.4.30(cef119.4.3,Chromium119.0.6045.159)版本升级体验支持H264及其他多个H264版本

Cefsharp119.4.30,cef119.4.3,Chromium119.0.6045.159 此更新包括一个高优先级安全更新 This update includes a high priority security update. 说明:此版本119.4.3支持H264视频播放(需要联系我),其他版本。.NETFramework 4.6.2 NuGet Gallery | CefSharp.WinForms 119.…

运动规划Motion-Planning随笔

online verification技术 实时安全校验技术:留一手 首先计算能否通过刹车这种方式得到一条安全轨迹,(让速不让道),当刹车有可能碰撞到行人或其他车辆时,则判断变道是否会产生碰撞。如果能变道&#xff0…

深度学习之七(深度信念网络和受限玻尔兹曼机器)

概念 深度信念网络(Deep Belief Networks,DBN)和受限玻尔兹曼机器(Restricted Boltzmann Machines,RBMs)都是无监督学习的模型,通常用于特征学习、降维和生成数据。 受限玻尔兹曼机器(RBM): 结构: RBM 是一个两层神经网络,包括一个可见层和一个隐藏层。这两层之间…

qt按照不同编码格式读取文字(UTF-16LE,UTF-8,UTF-8BOM,UTF-16BE)

enum class EncodingFormat : int {ANSI 0,//GBKUTF16LE,UTF16BE,UTF8,UTF8BOM, }; EncodingFormat VideoPlayer::FileCharacterEncoding(const QString &fileName) {//假定默认编码utf8EncodingFormat code EncodingFormat::UTF8;QFile file(fileName);if (file.open(QI…

「 系统设计 」 为什么要做架构分层?

「 系统设计 」 为什么要做架构分层? 参考&鸣谢 3.设计模式之分层思维:为什么要做代码分层架构? 从零开始学架构(八)分层架构和设计模式 架构模式之分层架构总结 文章目录 「 系统设计 」 为什么要做架构分层&…

解决 IDEA下VUE项目 @符号无法识别的问题

根目录新建jsconfig.json {"compilerOptions": {"baseUrl": "./","paths": {"/*": ["src/*"]}},"exclude": ["node_modules","dist"] }

IT支持团队的绩效指标和最佳实践

一名员工在远程时因笔记本问题寻求IT支持,尽管他们多次尝试排除故障,但由于缺乏专业知识,最终还是无法访问工作所需的应用程序。这时,他们需要一名专业的 IT 技术人员来指导他们,但他们只能等待有人注意到并回应他们的…

海报设计必备:揭秘5款炙手可热的设计工具

1.即时设计:能实现在线协作的海报设计软件 即时设计作为 2020 年上线的国产设计工具,目前已经有了超百万的注册用户,获得了广大设计师的一致好评。与其他传统海报设计软件相比,即时设计具有这几个优点:一是所有功能都…

Chrome 访问不了项目?10080端口 ERR_UNSAFE_PORT:问题原因 / 解决方案

文章目录 被禁用端口列表解决方法方法一、更换端口 / 使用代理 / 使用域名方法二、对浏览器下手WindowsMac 最近有客户反馈,在chrome浏览器中访问不了项目,其他浏览器都是正常的。 ?奇了怪了,难道客户对chrome做了什么操作&#x…

Docker | Docker入门安装

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏:Docker系列 ✨特色专栏: My…

探索WebStorm 2023 Mac/win:最强大的JavaScript开发工具

在当今的软件开发领域,JavaScript已经成为了一种不可或缺的编程语言。而在众多的JavaScript开发工具中,WebStorm一直以其强大的功能和友好的用户界面脱颖而出。现在,我们迎来了全新的WebStorm 2023版本,它将带给开发者们更加出色的…

有机纺织品OCS认证

【有机纺织品OCS认证】 有机产品是指按照这种方式生产和加工的产品。产品符合国际或者国家有机产品要求标准,并通过国家认证机构认证的一切农副产品及其加工品,包括粮食、蔬菜、水果、奶制品、禽畜产品、天然纤维等。 有机纺织品认证是指在使用经过国际或…

华中科技大学李松课题组,利用机器学习预测多孔材料水吸附等温线

多孔材料的水吸附等温线是一个非常重要的参数,但这一参数的获得并不容易。这是因为多孔材料种类过多、结构多元,通过实验和计算的方式获得水吸附等温线数据成本过高,耗时过长。 华中科技大学的李松课题组,建立了一个两步机器学习模…

LeetCode [简单] 283. 移动零

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 请注意 ,必须在不复制数组的情况下原地对数组进行操作。 283. 移动零 - 力扣(LeetCode) 思路: 快慢指针&…

可以在uni-app使用的类vconsole.js插件

兴致勃勃在uni-app项目引入调试工具vconsole.js结果真机调试页面空白 怎么办?! 别着急 paradox老师有方法 替代插件下载地址:直接下载插件并引入HbuilderXuni_modules插件 - 类Vconsole APP端调试工具 - HF调试器 - DCloud 插件市场 下载完成在main.js中引入&…

鸿蒙开发环境搭建-deveco-studio 开发工具安装问题()

从华为官网下载工具deveco-studio, 下载地址 HUAWEI DevEco Studio和SDK下载和升级 | HarmonyOS开发者 这是下载后的工具 1、一步步安装步骤 报错了,一般安装都会报这个错误 看似问题不小,其实, 继续下步,就正常了&#xff0c…

栈回溯--在栈里挑出返回地址

GNU Arm Embedded Toolchain project files : GNU Arm Embedded Toolchain arm-none-eabi-addr2line -e F103_Moduel.axf -a -f 08000350 08001d94 0800260c 汇编中: ;HardFault_Handler ; PROC ; EXPORT HardFault_Handler …

神命令tree的魅力你get到了吗?

背景 日常工作中,有时候为了明确表达自己的意思,往往需要输出对应的目录层级结构,手动一个个输入往往显得不那么高级,效率相对较低,这时候拥有可以一键输出目录结构并且可以快速转化为文本的工具就比较方便&#xff0…

工业I/O模块的功能和应用介绍

在工业领域中,不同的设备常常适配不同的通信协议,不同的协议之间无法直接互通,导致现场实施过程中困难重重。工业io模块可以将各种现场信号转化为数字信号,然后传输给控制器进行处理,实现不同设备之间的互通&#xff0…

抖音直播招聘报白企业或者人力资源公司怎么做?

抖音直播招聘报白是指进入抖音的白名单,允许在直播间或小视频中发布招聘或找工作等关键词。否则会断播、不推流、限流。抖音已成为短视频流量最大的平台,但招聘企业数量较少。抖音招聘的优势在于职位以视频、直播方式展示,留存联系方式更加精…