发布订阅模式(观察者模式)
发布订阅也叫观察者模式
发布 && 订阅
// 观察者模式(发布订阅)
// 发布者
class Publisher {
/**
* 构造函数:
* 定义一个存放所有观察者的数组
*/
constructor() {
this.subs = [];
}
/**
* 判断是否是 Subscriber 类的实例
* @param {*} subscriber
*/
isSubscriber(subscriber) {
return subscriber instanceof Subscriber;
}
/**
* 添加订阅者
* @param {*} Subscriber
*/
addSubscriber(Subscriber) {
if (!this.isSubscriber(Subscriber)) {
throw new Error("The parameter is must be instanceof Subscriber");
}
this.subs.push(Subscriber);
}
/**
* 移除订阅者
* @param {*} Subscriber
*/
removeSubscriber(Subscriber) {
if (!this.isSubscriber(Subscriber)) {
throw new Error("The parameter is must be instanceof Subscriber");
}
this.subs.forEach((item, index) => {
if (item === Subscriber) {
this.subs[index] = null;
}
});
}
/**
* 通知所有订阅者执行
* @param {...any} args
*/
notify(...args) {
this.subs.forEach(item => {
if (this.isSubscriber(item)) {
item.exec(...args)
}
});
}
}
// 订阅者
class Subscriber {
/**
* 构造函数:
* 在初始化实例的时候必须传入一个函数
* 将这个函数fn挂载到实例上
* @param {*} fn
*/
constructor(fn) {
if (typeof fn !== "function") {
throw new Error("The parameter is must be function");
}
this.fn = fn;
}
/**
* 确保每个实例都有一个exec方法
* 在发布者通知执行的时候执行实例上的fn方法
*/
exec() {
this.fn();
}
}
使用
const publisher = new Publisher();
const w1 = new Subscriber(function () {
console.log(1);
});
const w2 = new Subscriber(function () {
publisher.removeSubscriber(w1);
console.log(2);
});
const w3 = new Subscriber(function () {
console.log(3);
});
publisher.addSubscriber(w1);
publisher.addSubscriber(w2);
publisher.addSubscriber(w3);
publisher.notify(); // 1 2 3
console.log("------------");
publisher.notify(); // 2 3