发布订阅
是一种消息范式,消息的发送者(称为发布者)不会将消息直接发送给特定的接收者(称为订阅者)。而是将发布的消息分为不同的类别,无需了解哪些订阅者(如果有的话)可能存在。同样的,订阅者可以表达对一个或多个类别的兴趣,只接收感兴趣的消息,无需了解哪些发布者(如果有的话)存在。
手动实现发布订阅的事例
//发布订阅模型
let SubPub = function() {
this.pubList = {};
//添加订阅
this.addPub = function(event, callback) {
if (!this.pubList[event]) {
this.pubList[event] = [];
}
this.pubList[event].push(callback);
}
//删除订阅
this.removePub = function(event, callback) {
if (!this.pubList[event] || !callback) return;
for (let i = 0; i < this.pubList[event].length; i++) {
if (this.pubList[event][i] === callback) {
this.pubList[event].splice(i, 1);
}
}
}
//发布
this.sub = function(event, data) {
this.pubList[event].forEach(item => {
item(data)
})
}
}
// 口罩到货后,小明要做的事情
function xiaoMing(data) {
console.log('口罩到货了,我要赶紧去买一些')
}
// 口罩到货后,小红要做的事情
function xiaoHong(data) {
if (new Date() > new Date('6/30/2021')) {
console.log('疫情应该结束了,不买口罩了')
} else {
console.log('赶紧去买口罩,不然就买不着了')
}
}
// 口罩到货后,小白要做的事情
function xiaoBai(data) {
if (data.price > 100) {
console.log('这口罩咋这么贵?不买了!')
} else if (data.price > 50) {
console.log('这口罩偏贵,先买10个用着,过段时间看能不能降价')
} else {
console.log('这批口罩价格还可以,买50个屯着')
}
}
//开始进行发布订阅
let subPub1 = new SubPub();
//小明 小红 小白订阅了mask事件(他们只关注事件本身,而不关心谁发布这个事件)
subPub1.addPub('mask', xiaoMing);
subPub1.addPub('mask', xiaoHong);
subPub1.addPub('mask', xiaoBai);
//小红删除了自己的mask订阅
subPub1.removePub('mask', xiaoHong);
//有人发布了mask事件,结算该事件所有订阅(他只关注事件本身,而不关心都有谁订阅了这个事件)
const newData = {
type: 'N95',
price: 30,
stock: 1000
}
subPub1.sub('mask', newData);