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

news/2024/7/10 1:36:28 标签: vue

发布-订阅模式也是经典的设计模式之一,它在前端很多地方都有应用,比如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)
        console.log(this,'this')
        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 this
        this.events[eventName].forEach(fn => {
            fn.apply(this, args)
        });
        return this
    }
    off(eventName, fn) {
        if (!this.events[eventName]) return this
        if (typeof fn === 'function') {
            this.events[eventName] = this.events[eventName].filter((f) => f !== fn)
            return this
        }
        this.events[eventName] = null
        return 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.niftyadmin.cn/n/5211564.html

相关文章

SAS9.2软件“OLE:对象的类没有在注册数据库中注册“问题的解决. 2023-11-24

操作系统平台: win7 sp1 32bit (6.1.7601.26321 (Win7 RTM)) 1.安装依赖库(必须) Microsoft Visual C 2005 Redistributable Microsoft Visual C 2008 Redistributable 官方下载地址: 最新受支持的 Visual C 可再发行程序包下载 | Microsoft Learn (安装好后,重新打开SAS9.…

1|1111

1、指定在每天凌晨4:00将该时间点之前的系统日志信息(/var/log/messages )备份到目录下/backup,备份后日志文件名显示格式logfileYY-MM-DD-HH-MM 2、配置ssh免密登陆:客户端主机通过redhat用户基于秘钥验证方式进行远…

重生之我是一名程序员 40 ——字符串函数(1)

哈喽啊大家晚上好!今天呢给大家带来点新的东西——字符串函数strcpy。 首先,让我来给大家介绍一下它。strcpy函数是C语言中的一个字符串函数,用于将一个字符串复制到另一个字符串中。其函数原型为: char* strcpy(char* dest, co…

Linux:Ubuntu实现远程登陆

1、查看sshd服务是否存在 Ubuntu默认是没有安装sshd服务的,所以,无法远程登陆。 检查22端口是否存在 netstat -anp 该命令执行后,查看不到22端口的进程。 如果netstat无法使用,我们需要安装一下netstat服务 sudo apt-get install…

Echarts 大屏注册自定义地图解析文件流报错问题解决

效果图: 1、首先通过后台接口获取到SVG图片的文件流,postman能够正确解析出文件流,前端调用api时需要设置返回的响应格式为image/svg+xml格式,否则解析失败 拿到文件流后是这样的 <?xml version="1.0" encoding="utf-8"?> <!-- Generator: …

linux -系统通用命令查询

有时候内网环境下&#xff0c;系统有些命令没有安装因此掌握一些通用的linux 命令也可以帮助我们解决一些问题查看 1.查看系统内核版本 uname -r2.查看系统版本 cat /etc/os-release3. 查看cpu 配置 lscpu4.查看内存信息 free [参数] 中各个数值的解释如下表 数值解释t…

人脑工作机制 基本工作原理 神经元 神经网络 学习和记忆 和身体的互动 模仿游戏

人脑的工作机制非常复杂&#xff0c;涉及多个层面的结构和功能。以下是一些关键点&#xff0c;用以概述人脑的基本工作原理&#xff1a; 基本单位 - 神经元&#xff1a; 人脑包含大约860亿个神经元。神经元是脑的基本工作和信号处理单位&#xff0c;通过树突接收信号&#xff0…

任意分圆环下的 RLWE:如何产生正确的噪声分布

参考文献&#xff1a; [Con09] Conrad K. The different ideal[J]. Expository papers/Lecture notes. Available at: http://www.math.uconn.edu/∼kconrad/blurbs/gradnumthy/different.pdf, 2009.[LPR10] Lyubashevsky V, Peikert C, Regev O. On ideal lattices and learn…