简介
观察者和目标要相互知道 发布者和订阅者不用互相知道,通过第三方实现调度,属于经过解耦合的观察者模式。
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();
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>发布订阅模式</title>
</head>
<body>
<script>
/*
1. 观察者和目标要相互知道
2. 发布者和订阅者不用互相知道,通过第三方实现调度,属于经过解耦合的观察者模式。
*/
const PubSub = {
message: {},
publish(type, data) {
// this.list.forEach((item) => item());
if (this.message[type]) {
return;
}
this.message[type].forEach((element) => {
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) {
//取消所有
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() {
console.log("testB", data);
}
function testC() {
console.log("testC", data);
}
PubSub.subscribe("A", testA);
PubSub.subscribe("A", testA);
PubSub.subscribe("B", testB);
// PubSub.subscribe(testB);
// PubSub.publish();
</script>
</body>
</html>
示例 2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>发布订阅</title>
<style>
.box {
display: flex;
height: 500px;
}
.box .left {
width: 150px;
background-color: skyblue;
}
.box .right {
flex: 1;
background-color: yellow;
}
</style>
</head>
<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>
<script>
const PubSub = {
message: {},
publish(type, data) {
// this.list.forEach((item) => item());
if (this.message[type]) {
return;
}
this.message[type].forEach((element) => {
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) {
//取消所有
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 () {
console.log(this.innerHTML);
PubSub.publish("UpdateBread", this.innerHTML);
};
}
</script>
</body>
</html>