发布订阅模式

69 阅读2分钟

发布订阅模式

一般用来处理 大型项目(框架)的封装

去书店买书

  • JS 曾经的流程

          1. 你去到书店, 问店员 有没有一本叫做 <JS 从入门到入土>
          2. 店员: 我们现在没有, 你下次再来吧
          3. 过一段时间后, 又去书店 问店员  有没有一本叫做 <JS 从入门到入土>
          4. 店员: 我们现在没有, 你下次再来吧
          5. 过一段时间后, 又去书店 问店员  有没有一本叫做 <JS 从入门到入土>
          6. 店员: 我们现在没有, 你下次再来吧
           ......
          89. 过一段时间后, 又去书店 问店员  有没有一本叫做 <JS 从入门到入土>
          90. 店员: 在XX位置有, 你去拿吧
    
  • 发布订阅模式:

          1. 你去到书店, 问店员 有没有一本叫做 <JS 从入门到入土>
          2. 店员: 我们现在没有, 然后你留下一个联系方式, 将来有了之后我电话通知你
          3. 过了一段时间, 有书本了, 店员通过电话联系到你, 触发了你的技能(触发了一个函数) 然后购买了书本
           JS 从入门到入土': [预约者1, 预约2, 预约3],
           颈椎病的预防': [预约1, 预约2, 预约3]
    
        class observer {
            constructor(name) {
                this.name = name    // 模拟店员的名字, 但是不重要

                this.msgList = {}   // 模拟店员的记录手册
            }

            // 购买不到书本 留下预约方式的时候执行
            add(type, fn) {
                if (this.msgList[type] === undefined) { // 当前分支执行, 表明这个 type 是第一次出现
                    this.msgList[type] = []     // 在第一次出现的时候, 给它赋值一个空数组, 后续的内容直接 push 到数组内就可以了
                }

                this.msgList[type].push(fn) // 此时的 this.msgList[type] 一定是一个数组, 所以直接将预约者push到数组中就可以了
            }

            // 一段时间后, 书本到了, 通知对应的预约者, 然后触发他们的技能(函数)
            tri(type) {
                this.msgList[type].forEach(item => item())  // 通过 传入的 type 找到对应的属性值, 然后遍历调用内部的所有函数
            }

            // 调用这个方法, 取消预约
            delName(type, fn) {
                this.msgList[type] = this.msgList[type].filter(item => item !== fn) // 找到对应的数组, 将你的联系方式 删掉
            }
        }

        const o1 = new observer('小刚')
        console.log(o1)

        // 书名
        const bookName1 = 'JS从入门到入土'
        const bookName2 = '颈椎病的预防'

        // 预约者的技能(函数)
        const fnA = () => console.log('我是张三, 我想购买这本书')
        const fnB = () => console.log('我是李四, 我想购买这本书')
        const fnC = () => console.log('我是王五, 我想购买这本书')

        // 新增两位预约者
        o1.add(bookName1, fnA)
        o1.add(bookName1, fnB)
        o1.add(bookName1, fnC)

        // 中间一位预约者, 取消了预约, 不要了
        o1.delName(bookName1, fnB)

        // 过了一段时间, 书本到了, 通知对应的预约者前来购买
        o1.tri(bookName1)

        console.log('有预约者之后的对象: ', o1)