JavaScript发布订阅者模式

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

  1. 定义发布者类。发布者最基本的两个属性:发送的消息,发送的人
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)}
  },
  ...
]
复制代码
  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原理既视感!网站

相关文章
相关标签/搜索