这是我参与11月更文挑战的第26天,活动详情查看:2021最后一次更文挑战
观察者模式
最后我们来看看观察者模式,这个模式,在前端其实已经很常用了,我们 DOM 事件监听就是观察者模式,那如果想用一些自定义事件呢?我们也可以自己实现一个观察者模式,来看这个例子。
首先我们创建了一个 EventEmitter 的类,它有一个 listeners 属性用来管理注册过的事件,然后我们仿照 dom 的事件方法,创建了 addEventListener、removeEventListener、emit 方法,分别表示创建,删除,触发事件。
注意这里因为需要支持一个事件被 addEventListener 多次,所以每个 event 对应的,应该是一个回调函数的数组,最后我们在使用它的时候,就可以先创建一个实例,然后再注册事件和触发事件。
type Handler = (data?: any) => void;
class EventEmitter {
listeners: {
[eventName: string]: Handler[];
}
addEventListener(eventName: string, handler: Handler) {}
removeEventListener(eventName: string, handler: Handler) {}
emit(eventName: string, data?: any) {}
}
const eventEmitter = new EventEmitter();
eventEmitter.addEventListener('customClick', () => {
console.log('custom clicked');
})
eventEmitter.emit('customClick');
习题:理解观察者模式,并计算下面结果
enum PUBLISH_TYPE {
AGE_SET,
AGE_GET
};
class Animal {
private _age: number = 0;
get age(): number {
// 广播(发布):有人获取 age 值了
publishSubscribeStation(PUBLISH_TYPE.AGE_GET, this._age) {
return this._age;
}
}
set age(_age: number) {
// 广播(发布):有人设置了 age 值了
publishSubscribeStation(PUBLISH_TYPE.AGE_SET, _age);
this._age = _age;
}
}
// 电视剧(订阅):收到一则广播消息
const publishSubscribeStation = (key: PUBLISH_TYPE, value: any) => {
switch(key) {
case PUBLISH_TYPE.AGE_SET: {
console.log(`set ${value}`);
};break;
case PUBLISH_TYPE.AGE_GET: {
console.log(`get ${value}`);
};break;
}
}
const panda = new Animal();
panda.age; // 结果?
panda.age = 10; // 结果?
答案:
get 0
set 10
解析:
观察者模式又叫发布订阅模式,当发布者的状态发生变化时,所有订阅者就会得到通知。
类 Animal
的 set age
函数和 get age
函数是发布行为的触发者。publishSubscribeStation
函数是发布行为的订阅者。
题目中使用了 get
和 set
关键字,对属性 _age
设置存值函数(setter)和取值函数(getter),每当取 age
属性时,就会调用 get age
函数,然后触犯发布订阅。每当设置 age
属性时,就会调用 set age
函数,然后触犯发布订阅。
题目逻辑本身比较简单,答案为 get 0
,set 10
。