发布订阅模式,又叫观察者模式,它定义了一种一对多的关系,让多个订阅者对象监听某一个发布者,发布者状态发生更新时派发信息给每一个订阅者。
举个例子,我想买一双AJ鞋,鞋店没货了,我给店员留个号码,我不关心店家什么时候到货。店家到货后店员会给我打电话通知我,我想要的鞋到货了,我可以去购买。
代码实现
// ES5 IIFE 实现
var Publisher = (function() {
var _subsMap = {} // 存储订阅者
return {
// 消息订阅
subscribe(type, cb) {
if(_subsMap[type]) {
if(_subsMap[type].indexOf(cb) === -1) {
_subsMap[type].push(cb)
}
} else {
_subsMap[type] = [cb]
}
},
// 消息退订
unSubscribe(type, cb) {
if(!_subsMap[type] || _subsMap[type].indexOf(cb) === -1) return
var idx = _subsMap[type].indexOf(cb)
_subsMap[type].splice(idx, 1)
},
// 消息发布
notify(type) {
if(!_subsMap[type]) return
var params = Array.prototype.slice.call(arguments)
_subsMap[type].forEach(function(cb) {
cb(params)
})
}
}
})()
function piXie(message) {
console.log('pipipi'+message)
}
Publisher.subscribe('运动鞋', message => console.log('AJ830'+message)) // 订阅运动鞋
Publisher.subscribe('运动鞋', message => console.log('JK960'+message)) // 订阅运动鞋
Publisher.subscribe('皮鞋', piXie) // 订阅皮鞋
Publisher.notify('运动鞋', '运动鞋到货~速来')
Publisher.notify('皮鞋', '皮鞋到货~速来')
Publisher.unSubscribe('皮鞋', piXie)
Publisher.notify('皮鞋', '皮鞋到货~速来2')
// ES6
class Publisher2 {
constructor() {
this._subsMap = {}
}
subscribe(type, cb){
if(this._subsMap[type]) {
if(!this._subsMap[type].includes(cb)) {
this._subsMap[type].push(cb)
}
} else {
this._subsMap[type] = [cb]
}
}
unSubscribe(type, cb) {
if(!this._subsMap[type] || !this._subsMap[type].includes(cb)) return
const idx = this._subsMap[type].indexOf(cb)
this._subsMap[type].splice(idx, 1)
}
notify(type, ...payload) {
if(!this._subsMap[type]) return
this._subsMap[type].forEach(cb => cb(...payload))
}
}
const adadis = new Publisher2()
function fanBuXie(message) {
console.log('139zzz'+ message)
}
adadis.subscribe('运动鞋', message => console.log('152xxx'+ message))// 订阅运动鞋
adadis.subscribe('运动鞋', message => console.log('138yyy'+ message))
adadis.subscribe('帆布鞋', fanBuXie)// 订阅帆布鞋
adadis.notify('运动鞋',' 运动鞋到货了 ~') // 打电话通知买家运动鞋消息
adadis.unSubscribe('帆布鞋', fanBuXie) //取消订阅帆布鞋信息
adadis.notify('帆布鞋',' 帆布鞋售罄了 T.T') // 打电话通知买家帆布鞋消息
;
发布-订阅模式的通用实现
- Publisher:发布者,当消息发生时负责通知对应订阅者
- Subscriber:订阅者,当消息发生时被通知的对象
- SubscriberMap:持有不同 type 的数组,存储有所有订阅者的数组
- type:消息类型,订阅者可以订阅的不同消息类型
- subscribe:该方法为将订阅者添加到 SubscriberMap 中对应的数组中
- unSubscribe:该方法为在 SubscriberMap 中删除订阅者
- notify:该方法遍历通知 SubscriberMap 中对应 type 的每个订阅者