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

发布订阅模式

Vue的事件机制使用:

发布订阅模式和观察者模式_第1张图片

模拟实现

注意:这里只模拟无参情况,其他的需要的话自行完善

// 事件触发器
class EventEmitter {
    constructor(){
        // {'click': [fn1, fn2, fn3, ...], 'change': [fn1,...]}
        this.subs = Object.create(null) // 传入 null 意味着 subs 不需要原型
    }
    // 注册事件
    $on(eventType, handler){
        this.subs[eventType] = this.subs[eventType] || []
        this.subs[eventType].push(handler)
    }
    // 触发事件
    $emit(eventType){
        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('change', ()=>{
    console.log('change1');
})
em.$on('change', ()=>{
    console.log('change2');
})
em.$on('other', ()=>{
    console.log('other');
})
em.$emit('click')
em.$emit('change')
// em.$emit('other')

观察者模式

// 发布者 - 目标
class Dep {
    constructor() {
        // 记录所有的订阅者
        this.subs = []
    }
    // 添加订阅者
    addSub(sub) {
        if(sub && sub.update){
            this.subs.push(sub)
        }
    }

    // 通知所有订阅者,调用所有订阅者的 update 方法
    notify() {
        this.subs.forEach(sub => {
            sub.update()
        })
    }
}

// 订阅者 - 观察者
class Watcher {
    update() { 
        console.log('update')
    }
}

// 测试
let dep = new Dep()
let watcher = new Watcher()

dep.addSub(watcher)
dep.notify()

总结

  • 观察者模式是由具体目标调度,比如当事件触发,Dep 就会去调用观察者的方法,所以观察者模式中的订阅者和发布者是存在依赖的。
  • 发布订阅模式是由统一调度中心调用,因此发布者和订阅者不需要知道对方的存在。
    发布订阅模式和观察者模式_第2张图片

你可能感兴趣的:(vue,vue.js,javascript,前端)