JavaScript发布订阅者模式

假如你要建立一个网站,通常来说会有许多用户。你作为一名管理者,有时候需要将重要的消息发布给你的用户。在软件开发领域,开发此功能往往用到发布订阅者模式。下面我以简单的javascript来说明。

  1. 定义发布者类。发布者最基本的两个属性:发送的消息,发送的人
function Publisher() {
  this.observers =[]; // 存储需要发布消息的人
  this.state="hello"  // 发送的消息
}
复制代码

除此之外,一个Publisher还需要有能够接纳新的订阅消息的人的功能,或者删除某个订阅者的功能,同时需要能够将消息发送出去的功能。

// 新增订阅者功能
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方法。每一个订阅者的类似结构如下:

[
  {
    name:'张三',
    update:(data)=>{console.log(data)}
  },
  {
    name:'李四',
    update:(data)=>{console.log(data)}
  },
  ...
]
复制代码
  1. 构造订阅者对象,由于每一个订阅者都有name属性和update方法。最简单的就是采用构造函数方法来实现
function Subscribe(name){
  this.name =name;
  this.update = function(data){
    console.log(data);
  };
}
复制代码
  1. 有了Subscribe模板,我们开始构造出每一个具体的订阅者实例出来。
let lisi = new Subscribe('lisi')
let xiaoming = new Subscribe('xiaoming')
复制代码
  1. 将构造的订阅人lisi 和 xiaoming 加入到发布者对象的observer中
let pb = new Publisher()
pb.addUser(lisi)
pb.addUser(xiaoming)
复制代码
  1. 发布者需要发布消息时:
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原理既视感!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值