Appearance
发布-订阅模式
发布者和订阅者互不知晓对方存在,而由第三方实现调度。属于观察者模式的改良版。
- 简单版
javascript
const PubSub = {
list: [],
publish(){
this.list.forEach(item => item())
},
subscribe(cb){
this.list.push(cb)
}
}
function testA(){
console.log("testA")
}
function testB(){
console.log("testB")
}
PubSub.subscribe(testA)
PubSub.subscribe(testB)
PubSub.publish()
- 进阶版
javascript
const PubSub = {
message: {},
publish(type, data){
// this.list.forEach(item => item())
if(!this.message[type])return
this.message[type].forEach(item => item(data))
},
subscribe(type, cb){
if(!this.message[type]){
this.message[type] = [cb]
}else{
this.message[type].push(cb)
}
},
unsubscribe(type, cb){
if(!this.message[type]) return
if(!cb){
// 取消所有当前type事件
this.message[type] && (this.message[type].length = 0)
}else{
this.message[type] = this.message[type].filter(item => item !== cb)
}
}
}
function testA(data){
console.log("testA", data)
}
function testB(data){
console.log("testB", data)
}
function testC(data){
console.log("testC", data)
}
PubSub.subscribe("A", testA)
PubSub.subscribe("A", testC)
PubSub.subscribe("B", testB)
小例子
例子还是观察者的例子
javascript
/*
// body部分
<header class="header">
路径
</header>
<div class="box">
<div class="left">
<ul>
<li>首页</li>
<li>用户管理</li>
<li>权限管理</li>
<li>新闻管理</li>
</ul>
</div>
<div class="right">
<div class="bread"></div>
</div>
</div>
*/
const PubSub = {
message: {},
publish(type, data){
// this.list.forEach(item => item())
if(!this.message[type])return
this.message[type].forEach(item => item(data))
},
subscribe(type, cb){
if(!this.message[type]){
this.message[type] = [cb]
}else{
this.message[type].push(cb)
}
},
unsubscribe(type, cb){
if(!this.message[type]) return
if(!cb){
// 取消所有当前type事件
this.message[type] && (this.message[type].length = 0)
}else{
this.message[type] = this.message[type].filter(item => item !== cb)
}
}
}
PubSub.subscribe("UpdateBread", function(data){
console.log("我是订阅者", data)
document.querySelector(".bread").innerHTML = data
})
let oli = document.querySelectorAll(".left li")
for(let i = 0; i < oli.length; i++){
oli[i].onclick = function(){
PubSub.publish("UpdateBread", this.innerHTML)
}
}