通过EventBus实现发布与订阅模式
模式 实现 发布 通过 订阅 EventBus
2023-06-13 09:13:55 时间
源码
点击这里前往Github获取本文源码。
背景
后注: 发布-订阅模式属于设计模式中的行为型模式,基本上和观察者模式相同,至于具体定义存在争议,这里不进行讨论。
在Vue
中,我们经常通过全局事件总线进行简单的组件间通信,那么究其原理其实并不难,本文就来着手实现一个这样的功能。
实现
代码不是很难,直接贴出来,后文会解释这些代码的作用:
class EventBus {
callbacks = {}
on(event, callback) {
// 第一处标记,下面会提到
const callbacks = this.callbacks[event] ||= new Set()
callbacks.add(callback)
return this
}
once(event, callback) {
const actual = (...args) => {
callback(...args)
this.remove(event, actual)
}
this.on(event, actual)
return this
}
emit(event, ...args) {
this.callbacks[event]?.forEach(callback => {
callback(...args)
})
return this
}
remove(event, callback = undefined) {
if (callback) {
this.callbacks[event]?.delete(callback)
} else {
delete this.callbacks[event]
}
return this
}
}
首先观察到所有函数都返回了this
,由此我们可以进行链式调用。下面逐一解释:
-
on(event, callback)
我们把传入的callback
添加到this.callbacks[event]
这个集合中,为了以后触发事件的时候被调用。 注意到我们在第一处标记,通过||=
短路赋值给this.callbacks[event]
一个空集合,并且把这个赋值表达式的结果给一个局部变量。并且由于集合是引用类型,之后我们就可以通过操作这个局部变量来影响到原数据了。 -
once(event, callback)
使用once
添加的回调函数只会被调用一次,方法体中我们把传入的函数包装了一层。这个函数被调用后会通过this.remove(event, actual)
删除本身,达到只调用一次的效果。 -
emit(event, ...args)
触发指定的事件,并且传入参数,方法体内部通过forEach
遍历所有的回调函数。 -
reomve(event, callback = undefined)
删除指定的事件。如果没有指定是哪一个回调,就把整个事件对应的回调函数都删除掉。
使用
通过下列代码测试这个简易框架的正确性:
const bus = new EventBus()
bus.on('foo', () => {
console.log('foo 1')
}).on('foo', () => {
console.log('foo 2')
}).emit('foo')
// foo 1
// foo 2
bus.remove('foo')
.emit('foo')
// it will do nothing
bus.on('bar', n => {
console.log('bar:', n)
}).once('bar', n => {
console.log('bar once:', n)
}).emit('bar', 3)
// bar: 3
// bar once: 3
bus.emit('bar', 3)
// bar: 3
读者可以到控制台试验一下,看看是否是预期效果。
相关文章
- vim编辑器,可以实现保存退出()_vim进入编辑模式如何保存并退出
- RabbitMQ 学习(四)---- 工作队列模式
- ie11兼容性视图设置怎么能自动兼容_ie11兼容模式ie8
- 策略模式最简洁的实现方式是?
- NFT元宇宙模式系统开发Demo(技术理念)NFT链游项目系统开发流程详情
- 五种方式实现 Java 单例模式
- java设计模式之工厂模式详解编程语言
- 使用Redis实现发布/订阅模式(redis发布与订阅)
- 模式实现Redis单例模式的优化策略(redis单例)
- 模式Java运用Redis实现合理过期模式(redisjava过期)
- 模式Oracle 数据库:如何关闭归档模式(oracle关闭归档)
- 使用MSSQL实现灵活的混合验证模式(mssql设置混合验证)
- 「借用Linux桥接新的编程模式」(桥接模式linux)
- Oracle数据库调整模式名的实现方式(oracle修改模式名)
- Redis自减实现的高效抢购模式(redis自减实现抢购)
- Android源码学习之工厂方法模式应用及优势介绍
- Java策略模式的简单应用实现方法
- android基础教程之夜间模式实现示例
- 浅析MVP模式中V-P交互问题及案例分享
- ruby、javascript、php中的观察者模式实现代码