发布订阅模式
三要素:订阅者,发布者,信号中心
我们假定存在一个信号中心,某个任务完成就向信号中心发布一个信号,其他任务可以向这个信号订阅这个模式,从而知道自己什么时候可以开始执行,这样的模式叫做发布订阅模式
代码实现:
<body>
<script>
// 事件触发器
class EventEmitter {
constructor() {
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()
});
}
}
}
const vm = new EventEmitter()
vm.$on('click', () => {
console.log('click1')
})
vm.$on('click', () => {
console.log('click122')
})
vm.$emit('click')
</script>
</body>
</html>
补充知识点:Object.create(null)
-
Object.create(null) 创建的对象是一个空对象,在该对象上没有继承 Object.prototype
-
原型链上的属性或者方法,例如:toString(), hasOwnProperty()等方法.
-
Object.create()方法接受两个参数:Object.create(obj,propertiesObject)
- obj:一个对象,应该是新创建的对象的原型
- propertiesObject:可选。该参数对象是一组属性与值,该对象的属性名称将是新创建的对象的属性名称
观察者模式
观察者模式没有信号中心,只有发布者和订阅者,并且发布者要知道订阅者的存在,
要素:
- 观察者:订阅者 watcher
- update()— 当事件发生时要做的事情
- 目标:发布者Dep
- subs:数组 存储所有的观察者
- addsub():方法 向数组中添加观察者
- notify():当事件发生时 调用所有的观察者的 update 方法
代码实现:
<script>
// 发布者 目标
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方法
update(){
console.log("update")
}
}
// 测试
const dep = new Dep()
const watcher = new Watcher()
dep.addSub(watcher)
dep.notify()
</script>
两者区别
观察者模式:
观察者模式是由具体目标调度,比如当事件触发的时候,Dep 就回去调用观察者的update方法,所以观察者的订阅者和发布者是存在依赖关系的
发布/订阅模式:
发布/订阅模式是由统一的调度中心调用,因此发布者和订阅者不需要知道对方的存在