先上代码:
发布订阅者模式
class EventEmitter {
constructor() {
this.subs = Object.create(null)
}
// 触发事件
$emit(eventType) {
if (this.subs[eventType]) {
this.subs[eventType].forEach(handle => {
handle()
})
}
}
// 注册事件
$on(eventType, handle) {
this.subs[eventType] = this.subs[eventType] || []
this.subs[eventType].push(handle)
}
}
// test
let eventEmitter = new EventEmitter()
eventEmitter.$on('click', () => {
console.log('click on')
})
eventEmitter.$on('click', () => {
console.log('click2 on')
})
eventEmitter.$emit('click')
根据代码举例:
粉丝订阅了博主的公众号,公众号相当于事件中心,订阅的动作就是$ on。
当博主在公众号上发布了文章时,相当于执行了$emit方法,它会通知到每一位订阅者。
观察者模式
// 发布者
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')
}
}
// test
let dep = new Dep()
let watcher = new Watcher()
dep.addSub(watcher)
dep.notify()
根据代码举例:
学生在教师听老师讲课,每位学生都是一个watcher,老师把每位watcher通过addSub方法加入到订阅者队列中。
当老师开始上课时,会通知大家,即执行notify。
学生们便执行update方法开始听课。
总结:
发布/订阅模式:由统一调度中心调用,调度中心隔离订阅者和发布者,所以他们不需要知道彼此是谁,彼此没有依赖关系。
观察者模式:由具体目标调度。当事件触发时,由目标Dep执行观察者的方法。所以订阅者与发布者存在依赖关系。