假如你要创建一个网站,一般来讲会有许多用户。你做为一名管理者,有时候须要将重要的消息发布给你的用户。在软件开发领域,开发此功能每每用到发布订阅者模式。下面我以简单的javascript来讲明。javascript
function Publisher() {
this.observers =[]; // 存储须要发布消息的人
this.state="hello" // 发送的消息
}
复制代码
除此以外,一个Publisher还须要有可以接纳新的订阅消息的人的功能,或者删除某个订阅者的功能,同时须要可以将消息发送出去的功能。java
// 新增订阅者功能
Publisher.prototype.addUser=function(obj) {
const nameList= this.observers.map(item=>{
return item.name;
})
if(nameList.indexOf(obj.name) < 0) {
this.observers.push(obj)
}
return this;
}
//删除订阅者功能
Publisher.prototype.deleteUser=function(obj){
let index = -1
this.observers.forEach((item,key)=>{
if(item.name === obj.name){
index = key
}
})
if(index !== -1) {
this.observers.splice(index,1)
}
return this
}
// 通知订阅者功能
Publisher.prototype.noticeUser=function(data){
this.observers.forEach((item)=>{
item.update(data)
})
}
复制代码
值得注意的是,上述通知订阅者的功能是经过遍历this.observers 并调用每个订阅者的update方法。因此每个订阅者须要对应有update方法。每个订阅者的相似结构以下:bash
[
{
name:'张三',
update:(data)=>{console.log(data)}
},
{
name:'李四',
update:(data)=>{console.log(data)}
},
...
]
复制代码
function Subscribe(name){
this.name =name;
this.update = function(data){
console.log(data);
};
}
复制代码
let lisi = new Subscribe('lisi')
let xiaoming = new Subscribe('xiaoming')
复制代码
let pb = new Publisher()
pb.addUser(lisi)
pb.addUser(xiaoming)
复制代码
pb.noticeUser("hello")
复制代码
至此一个最简单的发布订阅者模式实现了,这里还有两点优化建议。
第一,上述构造出来的lisi,xiaoming都会自动有update方法,而且update的行为都是同样的,若是须要例如xiaoming的update与其余不一样,只须要从新定义便可函数
xiaoling.update=(data)=>{console.log("hello"+data)}
pb.addUser(xiaoling)
复制代码
第二, 发布者须要手动调用pb.noticeUser()去通知state消息,能够作到state变更了自动去调用pb.noticeUser()吗?能够的,此时 Object.defineProperty()就派上用场了优化
let pb = new Publisher()
Object.defineProperty(pb,'state',{
set:function(newVal,) {
let a = this
debugger
pb.noticeUser(newVal)
}
})
pb.addUser(lisi)
pb.addUser(xiaoming)
pb.state = '123'
//pb.noticeUser()
复制代码
若是state变化了将自动触发pb.noticeUser(),实现自动通知功能,是否是有点Vue原理既视感!网站