发布订阅模式-前端设计模式

首先理解 发布和订阅

利用报刊的场景 小时候,家里人有看报刊的习惯, 会和联系送报刊的人 告诉他,我需要什么类型的报刊。 - 这个可以被称为订阅 接着报刊到了,送报刊的人,会把报刊送到我家。-这属于发布

在程序中怎么来定义的呢? 还是利用数组的方法是实现 type 是 你定义报刊的类型 fn 是一个函数,可以理解为报刊的内容

let event = {
          
   
            add(type, fn) {
          
   
                if (!this[type]) {
          
   
                    this[type] = []
                }
                this[type].push(fn)
            }
        }

trigger 这个函数 就是调用了我们存在数组里面的函数 它表示发布的意思。

let event = {
          
   
            add(type, fn) {
          
   
                if (!this[type]) {
          
   
                    this[type] = []
                }
                this[type].push(fn)
            },

            trigger(type) {
          
   
                if(!this[type]) return
                this[type].forEach(v => {
          
   
                    v()
                })
            }
        }

下面是完整的实现代码 说下优点和缺点: 这种模式很好的维护和二次开发 它会将不同的功能分开来,低耦合性

缺点 就是 可读性比较差 如果不了解这种模式的,第一次看起来就很会不理解

其实 promise.all方法也是发布订阅的思想在里面

let event = {
          
   
            add(type, fn) {
          
   
                if (!this[type]) {
          
   
                    this[type] = []
                }
                this[type].push(fn)
            },

            trigger(type) {
          
   
                if(!this[type]) return
                this[type].forEach(v => {
          
   
                    v()
                })
            }
        }

        var btn = document.querySelector("#btn")
        btn.addEventListener(click, function () {
          
   
            console.log(登录成功);
            event.trigger(login)
        })

        event.add(login, function () {
          
   
            console.log(登录之后获取用户头像);
        })
        event.add(login, function () {
          
   
            console.log(登录之后获取用户的历史听歌记录);
        })
        event.add(login, function () {
          
   
            console.log(登录之后给用户推荐歌单);
        })
        event.add(login, function () {
          
   
            console.log(登录之后给用户推荐VIP优惠券);
        })
        console.log(event);

类方法写的发布订阅模式

// 订阅者
        class Subject {
          
   
            constructor() {
          
   
                this.state = 0,
                this.observers = []
            }
            // 获取state的值 不重要
            getState() {
          
   
                return this.state
            }
            setState(state) {
          
   
                this.state = state
                this.notifyAllObservers()
            }
            notifyAllObservers() {
          
   
                this.observers.forEach((observer=> {
          
   
                    observer.update()
                }))
            }
            attach(observer) {
          
   
                this.observers.push(observer)
            }
        }

        class Observer {
          
   
            constructor(name, subject) {
          
   
                this.name = name
                this.subject = subject
                this.subject.attach(this)
            }
            update() {
          
   
                console.log(`${
            
     this.name} updata, state: ${
            
     this.subject.getState()}`);
            }
        }
        let s = new Subject()
        let o1 = new Observer(o1, s)
        let o2 = new Observer(o2, s)
        let o3 = new Observer(o3, s)
        s.setState(1)
        s.setState(2)
        s.setState(3)
经验分享 程序员 微信小程序 职场和发展