JavaScript发布-订阅模式与开发实践(中)

57 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 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

这样我们就成功实现了一个发布-订阅模式了🤩

不过,这只是简单版本的。严格来讲我们还需要在订阅时,判断是否重复订阅/只在必要时通知等等

尾声

通过本章,相信之前不了解发布-订阅模式的你已经能够从一个网页中发现许多的发布-订阅模式了。