# 观察者模式
# 参考
# 定义
建立一种对象间的一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。
发布订阅模式是最常用的一种观察者模式的实现,发布订阅模式让两个对象低耦合的联系在一起,双方不必清楚彼此的实现,依然能够进行互相通信。
# 应用场景
在JavaScript开发中常见的事件模型,就属于发布订阅模式。另外常见的dom绑定事件,ajax异步请求回调都属于发布订阅模式的一种体现。
# 优点
- 实现了对象的解耦,以及在异步编程中时间的解耦。
# 缺点
- 为了实现对象间的解耦,弱化了对象之间的联系。过度的使用,使得对象必要的联系被深埋在后,会导致程序难以跟踪、维护。
# 代码实例
// JavaScript发布-订阅模式的简单实现
class EventEmitter {
private events: object = {}
on(eventName: string, fn: Function): void {
Array.isArray(this.events[eventName]) ? this.events[eventName].push(fn) : (this.events[eventName] = [fn])
}
emit(eventName: string): boolean {
if (this.haveEvents(eventName)) {
this.events[eventName].forEach(fn => {
fn()
})
return true
}
return false
}
off(eventName: string, fn?: Function): boolean {
if (this.haveEvents(eventName)) {
const fnIndex = this.events[eventName].findIndex(f => f === fn)
if (typeof fn === 'function' && fnIndex >= 0) {
this.events[eventName].splice(fnIndex, 1)
} else {
this.events[eventName] = []
}
return true
}
return false
}
haveEvents(eventName: string): boolean {
return this.events[eventName] && this.events[eventName].length
}
}
const EE = new EventEmitter()
const log1 = () => console.log('1')
const log1_1 = () => console.log('1_1')
const log1_1_1 = () => console.log('1_1_1')
const log2 = () => console.log('2')
EE.on('event1', log1)
EE.on('event1', log1_1)
EE.on('event1', log1_1_1)
EE.on('event2', log2)
EE.off('event1', log1_1)
EE.emit('event1')
EE.emit('event2')
console.log(EE)