携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第22天,点击查看活动详情
前言
作为一个前端切图仔,少有和各类设计模式打交道。但这不影响我们学习设计模式的思维,来提升我们的代码水平。
本章通过讲解发布-订阅模式,希望能够让你对设计模式更一步的学习。
本章学习内容👇
- 发布-订阅模式在前端的运用
发布-订阅模式在前端的运用
DOM事件
在javaScript开发中,我们一般用事件模型来替代传统的发布—订阅模式。
事件模型是?🤔
其实很简单,我们只要在DOM节点上绑定一个事件函数就组成了事件模型。这也符合我们发布-订阅模式:
- 事件函数作为
订阅者,订阅DOM节点的事件 DOM节点作为发布者,在触发事件时通知事件函数
接下来,我们在浏览器中尝试下这一点👇
document.addEventListener('click',function (){
alert('触发订阅')
},false)
document.body.click()//触发订阅
通过订阅(监听)浏览器文档模型的点击事件,并传入一个供给通知状态的事件函数,完成了发布—订阅模式。
自定义事件
除了**DOM事件**外,我们还经常会实现一些自定义的事件。
什么是自定义事件呢?简单来说就是对象之间的关联,一个对象监听另外一个对象的属性,围绕属性变化展开发布—订阅。
这种实现非常常见,比如说Vue中的响应式原理就是基于依赖注入实现的。
对这部分感兴趣的读者可以参考:《
Vue2响应式原理以及实现》
现在,我们一起来实现一个简单的发布-订阅模式。首先想想这个模式应该如何逐步实现?
- 首先需要一个发布者和若干个订阅者
- 然后发布者需要添加一个缓存池,池中对应着每个订阅者相应的回调函数
- 当事件发生/状态改变时,发布者会遍历这个缓存池,依次通知对应的订阅者(触发对应的回调函数)
代码如下👇
class Publisher{
constructor() {
this.cache = []
}
dependent(callback){
this.cache.push(callback)
}
trigger(){
this.cache.forEach((callback)=>{
callback()
})
}
}
let publisher = new Publisher()
let subscriber1 = {
name:'one',
}
let subscriber2 = {
name:'two'
}
publisher.dependent(()=>{console.log(subscriber1.name)})
publisher.dependent(()=>{console.log(subscriber2.name)})
publisher.trigger()
控制台输出
one
two
这样我们就成功实现了一个发布-订阅模式了🤩
不过,这只是简单版本的。严格来讲我们还需要在订阅时,判断是否重复订阅/只在必要时通知等等
尾声
通过本章,相信之前不了解发布-订阅模式的你已经能够从一个网页中发现许多的发布-订阅模式了。