发布订阅模式

132 阅读2分钟

发布订阅模式

  • 一般用来处理大型项目(框架)的封装
  • 自行搜索: vue2.0 响应式实现原理

帮助理解

 *    去书店买书
 *        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) {
        // 通过这个函数可以向this.msgList内添加内容,后续方便维护
        if(this.msgList[type] === undefined) {// 当前分支执行,表明这个type是第一次出现
          this.msgList[type] = [] //第一次出现的时候,给它赋值一个空数组,后续的内容直接push到数组内就可以了
        }
        this.msgList[type].push(fn) //此时的 this.msgList[type] 一定是一个数组,所以直接将预约者push到数组中就可以了
      }
      // 一段时间后,书本到了,通知对应的预约者,然后触发他们的技能(函数)
      try(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 = 'JS从入门到入土'
    // 预约者的技能(函数)
    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.try(bookName1)
    console.log('有预约者之后的', o1)