手写实现vue 发布 订阅模式和观察者模式

发布订阅模式和观察者模式

  • 发布/订阅模式
    • 订阅者
    • 发布者
    • 信号中心

我们假定,存在一个"信号中心",某个任务执行完成,就向信号中心"发布"(publish)一个信号,其他任务可以向信号中心"订阅"(subscribe)这个信号,从而知道什么时候自己可以开始执行。这就叫做 “发布/订阅模式”(publish-subscribe pattern)

Vue 的自定义事件

let vm = new Vue() 

vm.$on('dataChange', () => {
	console.log('dataChange')
}) 

vm.$on('dataChange', () => {
	console.log('dataChange1')
}) 

vm.$emit('dataChange')

兄弟组件通信过程

// eventBus.js 
// 事件中心 
let eventHub = new Vue()
// ComponentA.vue 
// 发布者 
addTodo: function() {
	// 发布消息(事件) 
	eventHub.$emit('add-todo', {
		text: this.newTodoText
	}) this.newTodoText = ''
}
// ComponentB.vue 
// 订阅者
created: function() {
	// 订阅消息(事件) 
	eventHub.$on('add-todo', this.addTodo)
}

发布 订阅模式

  // 事件触发器
    class EventEmitter {
      constructor () {
        // { 'click': [fn1, fn2], 'change': [fn] }
        this.subs = Object.create(null)
      }

      // 注册事件
      $on (eventType, handler) {
        this.subs[eventType] = this.subs[eventType] || []
        this.subs[eventType].push(handler)
      }

      // 触发事件
      $emit (eventType) {
        if (this.subs[eventType]) {
          this.subs[eventType].forEach(handler => {
            handler()
          })
        }
      }
    }

    // 测试
    let em = new EventEmitter()
    em.$on('click', () => {
      console.log('click1')
    })
    em.$on('click', () => {
      console.log('click2')
    })
    em.$on('fn', ()=> {
    	console.log('fn')
    })
    em.$emit('click')
    em.$emit('fn')

观察者模式

    // 发布者-目标
    class Dep {
      constructor () {
        // 记录所有的订阅者
        this.subs = []
      }
      // 添加订阅者
      addSub (sub) {
        if (sub && sub.update) {
          this.subs.push(sub)
        }
      }
      // 发布通知
      notify () {
        this.subs.forEach(sub => {
          sub.update()
        })
      }
    }
    // 订阅者-观察者
    class Watcher {
      update () {
        console.log('update')
      }
    }

    // 测试
    let dep = new Dep()
    let watcher1 = new Watcher()
    let watcher2 = new Watcher()
    
    dep.addSub(watcher1)
    dep.addSub(watcher2)
    
    dep.notify()

两者的区别
手写实现vue 发布 订阅模式和观察者模式_第1张图片

你可能感兴趣的:(javascript)