发布-订阅模式 实现监听
一、应用场景
由于多个页面需要用到同一个状态或属性,并且需要在状态或属性发生变化时,可以及时做出对应的操作。正常情况下,第一反应肯定是通过轮询,也就是定期地去主动获取,这种方式会产生一些不必要的时间开支。
为减少代码耦合,参考发布-订阅模式(Subscribe/Publish)。
发布-订阅模式和观察者模式很相似(博主有时候分不清),有人说发布-订阅就是观察者的一种。按博主的区分,发布-订阅它有调度中心,发布者和订阅者之间没有直接联系。
二、实现
1、调度中心:StatusManager
export class StatusManager {
// 订阅的任务列表 {"state", [callback1, callback2]}
static TaskList = new Map();
/**
* 订阅方法
* stateName 要订阅的属性
* callback 监听的回调
*/
static Subscribe(stateName, callback) {
if (TaskList.has(stateName)) {
TaskList.get(TaskList).push(callback);
} else {
let list = new Array().push(callback);
TaskList.set(stateName, list);
}
}
/**
* 发布方法
* stateName 要发布的属性
* data 要发布的值
*/
static Publish(stateName, data) {
if (TaskList.has(stateName)) {
for (let task of TaskList.get(TaskList)) {
setTimeout(() => { task(data) }, 0); // setTimeout是为了让回调异步执行
}
}
}
}
2、发布者(修改状态的地方):Publisher
// 发布者
class Publisher {
StatusManager.Publish("state", 100);
}
3、订阅者1:SubscriberOne
// 监听的地方1
class SubscriberOne {
StatusManager.Subscribe("state", (data) = > {
console.log("state 发生改变了 SubscriberOne 收到了", data);
});
}
4、订阅者2:SubscriberTwo
// 监听的地方2
class SubscriberTwo {
StatusManager.Subscribe("state", (data) = > {
console.log("state 发生改变了 SubscriberTwo 收到了", data);
});
}
- 需要监听的地方,调用StatusManager.Subscribe实现订阅
- 状态改变的地方,调用StatusManager.Publish发布
- 订阅和发布对应的key值要保持一致
- 当发布者调用了StatusManager.Publish,调度中心就会把对应订阅的callback一一执行