1.发布订阅模式(发布者、订阅者、信号中心)
一个简单的例子来通俗的理解这个模式的概念:假如你是学生的家长,你的孩子每次考完试你都想马上知道孩子的成绩是多少,每次考完学校的班级都会统计成绩,家长总是要去问学校的班级成绩出来没成绩出来没,现在有一种模式,只要家长在班级里面订阅了孩子的成绩,只要成绩出来了,就相当于出发了班级里的事件,班级的老师就马上通知订阅了成绩的家长,在这个过程中,家长就是订阅者,老师就是发布者。这个班级就是一个事件中心。
概念:我们假定,存在一个”信号中心",某个任务执行完成,就向信号中心发布一个信号,其他任务可以向信号中心订阅这个信号,从而知道什么时候自己开始执行。这个就叫做”发布/订阅模式‘
使用场景1:vue的自定义事件
let vm = new Vue() vm.$on('dataChange',()=>{ console.log('dataChange1') }) vm.$on('dataChange',()=>{ console.log('dataChange2') }) vm.$emit('dataChange')
使用场景2:兄弟组件的通信过程
//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) }
发布订阅的实现
//发布订阅模式 let vm =new Vue() // {'click':[fn1,,fn2],'change':[fn]} class EventEmitter{ constructor(){ this.subs = Object.create(null) console.log('this',this.subs) } //注册事件 $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.$emit('click')
结果:
2.观察者模式(发布者、订阅者)
举个例子:
假设你正在找一份软件工程师的工作,对“XX公司”很感兴趣。所以你就联系了他们的HR,给了他你的联系电话。他保证如果有任何职位空缺都会通知你。这里还有几个候选 人也我你一样很感兴趣。所以职位空缺大家都会知道,如果你回应了他们的通知,他们就会联系你面试。
- 观察者-Watcher
update():当事件发生的时候,具体要做的事情
- 目标(发布者):Dep
subs数组:存储所有的而观察者
addSub():添加观察者
notify():当事件发生,调用所欲的观察者的update()方法
- 没有事件中心
//发布者 -目标 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 watcher = new Watcher() dep.addSub(watcher) dep.notify()
结果:
总结: