發佈訂閱模式,又叫觀察者模式,它定義了一種一對多的關係,讓多個訂閱者對象監聽某一個發佈者,發佈者狀態發生更新時派發信息給每一個訂閱者。
舉個例子,我想買一雙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 的每個訂閱者