网站首页 > 技术文章 正文
前言
在面试场景题中,发布订阅占有举足轻重地地位.发布订阅模式是一种消息通信模式,这一模式,消息的发送者不会将消息直接发送给特定的订阅者.发布者发布信息,如果有订阅者订阅了该消息就会得到这个信息.那么我们手写又是如何实现呢?
正文
组件通信中的发布订阅
我们先从vue中的组件通信中的子传父通信的案例来看.在vue中的字组件我们通过defineEmits来声明一个事件,在父组件中订阅该事件.
vue组件通讯中的发布订阅者,在子组件中负责创建事件并且发布订阅事件,在父组件中负责订阅事件并获取到子组件给到的参数.那么我们接下来如何实现手写呢?
手写发布订阅
class Event {
constructor() {
this.event = {},
this.onceFn = []
}
on(type, fn) {
if (!this.event[type]) {
this.event[type] = []
}
this.event[type].push(fn)
}
emit(type, data) {
this.event[type].forEach((item) => {
item(data)
})
}
off(type, fn) {
this.event[type] = this.event[type].filter((item) => item !== fn)
}
once(type, fn) {
if (this.onceFn.includes(fn)) {
return
}
this.onceFn.push(fn)
this.on(type, fn)
}
}
在上述代码中我们使用类构造函数创建了一个Event函数,在构造函数中我们创建了四个函数on(),emit(),off(),once().且在 constructor()创建了一个对象this.evnet用于存储时间及其对应的处理器列表,数组this.onceFn用于存储只执行一次的函数.那么我们创建的四个函数分别时什么作用呢?
on()是用于订阅事件的.那么这个订阅的思路是如何实现的呢?on()接收两个参数type和fn,其中type表示的是事件类型,fn是事件函数。if (!this.event[type])在对象中如果不存在该属性,this.event[type] = []就添加该属性并把该属性的值设置成一个数组,最后将该事件type的函数存到数组中.这就是on()的作用
emit()发布订阅,接收两个参数type,data这个data是代表函数中的参数,我们使用forEach循环遍历this.evnet[type]数组并执行函数.
off()这是取消订阅事件,它接收参数的意义和on()其实是一模一样的我们使用filter过滤器去除事件类型为type中的某一个函数fn并重新把它赋值给this.event[type].这样的话我们就是实现了取消订阅.
once()也是接收两个参数.但是它的作用是保证同一事件函数值被调用一次,防止被多次调用.首先我们会检查在数组onceFn中是否存在只需要执行一个的函数,如果存在的话,就直接return返回就就不会走下一步.如果存在,就先将该函数添加到数组onceFn中,然后调用on()订阅该事件.
我们来测试订阅
const eventEmitter = new Event();
// 订阅事件
eventEmitter.on('message', (data) => {
console.log('Message:', data);
});
这是我们订阅事件,我们不会有打印结果的,只有发布之后才会有打印eventEmitter.emit('message','xixi')
这里我们先订阅事件然后取消订阅,最后再发布事件
const eventEmitter = new Event();
function Message(data){
console.log(data);
}
// 订阅事件
eventEmitter.on('message',Message);
eventEmitter.off('message',Message);
eventEmitter.emit('message','xixi')
此时我们得到的结果是不会打印内容的。
上述就是手写一个发布订阅,希望对大家伙有所帮助,谢谢大家的阅读!!!
- 上一篇: 前端面试常问的n个问题
- 下一篇: 学员分享:回答字节跳动前端面试8道题,就像跟坐过山车样刺激
猜你喜欢
- 2024-12-13 前端安全相关面试题
- 2024-12-13 前端面试题:手写 call
- 2024-12-13 学员分享:回答字节跳动前端面试8道题,就像跟坐过山车样刺激
- 2024-12-13 前端面试常问的n个问题
- 2024-12-13 前端面试 JS 改变原数组 #前段学习
你 发表评论:
欢迎- 05-30为什么说网上的md5加密解密站都是通过彩虹表解密的?
- 05-30一文读懂md5,md5有什么用,什么是md5加盐
- 05-30Java md5加密解密数据
- 05-30MD5是什么?如何进行MD5校验?
- 05-30专家教你简单又轻松的MD5解密方法,一看就会
- 05-30多学习才能多赚钱之:vscode怎么安装插件
- 05-30VSCode无限画布模式(可能会惊艳到你的一个小功能)
- 05-30VSCode神级Ai插件Cline:从安装到实战【创建微信小程序扫雷】
- 最近发表
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端react (48)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端路由 (55)
- 前端数组 (65)
- 前端定时器 (47)
- Oracle RAC (73)
- oracle恢复 (76)
- oracle 删除表 (48)
- oracle 用户名 (74)
- oracle 工具 (55)
- oracle 内存 (50)
- oracle 导出表 (57)
- oracle 中文 (51)
- oracle链接 (47)
- oracle的函数 (57)
- mac oracle (47)
- 前端调试 (52)
- 前端登录页面 (48)
本文暂时没有评论,来添加一个吧(●'◡'●)