發(fā)布訂閱模式(觀察者模式)
發(fā)布訂閱也叫觀察者模式
發(fā)布 && 訂閱
// 觀察者模式(發(fā)布訂閱)
// 發(fā)布者
class Publisher {
/**
* 構(gòu)造函數(shù):
* 定義一個(gè)存放所有觀察者的數(shù)組
*/
constructor() {
this.subs = [];
}
/**
* 判斷是否是 Subscriber 類的實(shí)例
* @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;
}
});
}
/**
* 通知所有訂閱者執(zhí)行
* @param {...any} args
*/
notify(...args) {
this.subs.forEach(item => {
if (this.isSubscriber(item)) {
item.exec(...args)
}
});
}
}
// 訂閱者
class Subscriber {
/**
* 構(gòu)造函數(shù):
* 在初始化實(shí)例的時(shí)候必須傳入一個(gè)函數(shù)
* 將這個(gè)函數(shù)fn掛載到實(shí)例上
* @param {*} fn
*/
constructor(fn) {
if (typeof fn !== "function") {
throw new Error("The parameter is must be function");
}
this.fn = fn;
}
/**
* 確保每個(gè)實(shí)例都有一個(gè)exec方法
* 在發(fā)布者通知執(zhí)行的時(shí)候執(zhí)行實(shí)例上的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