公布订阅模式
- 利用场景:vue事件监听(兄弟组件之间传递数据)、nodejs事件监听
- 成员:
- 发布者:在发布者中调用 notify()
- 订阅者:在订阅者中调用 addSub()
- 事件核心:subs数组、addSub()(也对应on)、notify()(对应emit)
// 事件核心let eventHub = new Vue()// 组件A:发布者addTodo: function (){ eventHub.$emit('add-todo', { text: this.newTodoText }) this.newTodoText = ''}// 组件B:订阅者created: function (){ eventHub.$on('add-todo',(e)=>{ })}
模仿实现代码:
<!DOCTYPE html><html><head> <meta charset='utf-8'> <meta http-equiv='X-UA-Compatible' content='IE=edge'> <title>公布订阅模式</title> <meta name='viewport' content='width=device-width, initial-scale=1'></head><script> // 公布订阅模式事件核心类 class PublishSubscribe{ constructor(){ this.subs = {} // Object.create(null) } // 订阅 addSub(eventType, handler) { this.subs[eventType] = this.subs[eventType] || [] this.subs[eventType].push(handler) } // 公布 notify(eventType){ if(this.subs[eventType]){ this.subs[eventType].forEach(handler => { handler() }) } } } // 公布订阅模式应用示例 // 1、vm 为事件核心实例对象 let vm = new PublishSubscribe() // 2、订阅音讯(在订阅者中调用,例如某个组件1中) vm.addSub("click",()=>{ console.log("click1") }) vm.addSub("click",()=>{ console.log("click2") }) vm.addSub("change",()=>{ console.log("change1") }) // 3、公布音讯(在发布者中调用,例如某个组件2中) vm.notify("click") vm.notify("change")</script><body> </body></html>
观察者模式
- 利用场景:vue响应式原理
- 成员:
- 发布者:为一个对象,领有subs数组、addSub()、notify()
- 订阅者(观察者):为一个对象,必须领有update()
模仿实现代码
<!DOCTYPE html><html><head> <meta charset='utf-8'> <meta http-equiv='X-UA-Compatible' content='IE=edge'> <title>观察者模式</title> <meta name='viewport' content='width=device-width, initial-scale=1'></head><script> // 1、发布者 class Dep{ constructor(){ this.subs = [] } addSub (sub){ if(sub && sub.update) this.subs.push(sub) } notify (){ this.subs.forEach(sub => sub.update()) } } // 2、订阅者、观察者 class Watcher{ constructor(name){ this.name = name } update(){ console.log("update:", this.name) } } // 应用观察者模式 let watcher1 = new Watcher("观察者1") let watcher2 = new Watcher("观察者2") let dep = new Dep() dep.addSub(watcher1) dep.addSub(watcher2) dep.notify()</script><body> </body></html>
公布订阅、观察者模式的区别?
公布订阅模式
- 有事件核心、发布者、订阅者三个成员;(事件核心的作用能够隔离发布者和订阅者,去除他们之间的依赖),所有的公布和订阅事件须要存储到事件核心外面。
- 事件更新 update() 解决逻辑在订阅时的回调函数中执行。
- 公布和订阅者是形象的,通常是在办法里调用 addSub() 和 notify() 。
- 一个发布者多个订阅者:订阅者执行屡次 addSub() 增加定义,发布者调用一个 notify() 告诉更新。
观察者模式
- 没有事件核心,只有发布者、订阅者两个成员。
- 发布者中存储所有订阅者 subs 且有增加订阅者的 addSub() 办法、告诉订阅者更新的 notify() 办法。订阅者中必须有一个 update() 办法。
- 公布和订阅者是一个对象。
- 一个发布者多个订阅者:发布者屡次增加观察者 dep.addSub(watcher),发布者告诉 dep.notify() 触发所有订阅者执行 update()。
特地鸣谢:拉勾教育前端高薪训练营;