当前位置:   article > 正文

发布-订阅模式(观察者模式)_发布订阅模式

发布订阅模式

定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。在js中,一般用事件模型来替代传统的发布-订阅模式

// 将发布---订阅的功能提取出来
let event = {
  // 缓存列表,存放订阅者订阅的事件和其回调函数
  clientList:{},
  // 增加订阅者订阅的事件和回调函数
  listen(key,fn){
    if(!this.clientList[key]){
        //如果没有订阅过此类消息,则给该类消息创建一个缓存列表 
        this.clientList[key] = [];
    }
    // 将订阅消息添加进消息缓存列表
    this.clientList[key].push(fn);
  },
  // 发布消息
  on(...args){
    let key = args.shift(),
        fns = this.clientList[key];
    if( !fns || fns.length === 0 ){ //没有绑定对应消息
        return false;
    }
 
    for(let fn of fns){  //通知订阅该消息的所有订阅者
        fn.call(this,args); //args是trigger时带上的参数
    }
 
  },
  // 取消订阅
  off(key,fn){
      let fns = this.clientList[key];
      if(!fns){
          return false;  //key对应的消息没有被人订阅,直接返回
      }
      if(!fn){ //没有传入fn,则表示取消key对应消息的所有订阅
          fns && ( fns.length=0 )
      }else{
        let index = fns.findIndex(function(val){
            return val===fn;
        });
        fns.splice(index,1); //删除订阅者的回调函数
        console.log('success');
      }
  }
};
 
// 给所有对象都动态安装订阅-分布功能
let installEvent = obj=>{
  for( let key in event ){
      obj[key] = event[key];
  }
};
 
let salesOffice = {};
installEvent(salesOffice);
 
salesOffice.listen('square88',fn1=price=>console.log('price='+price));
salesOffice.listen('square88',fn2=price=>console.log('price='+price));
salesOffice.on('square88',8000);
salesOffice.off('square88',fn1);
salesOffice.on('square88',8000);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
// 全局发布--订阅对象
let Event = {
  // 缓存列表,存放订阅者的回调函数
  clientList:{},
  // 增加订阅者--监听
  listen(key,fn){
    if(!this.clientList[key]){
        //如果没有订阅过此类消息,则给该类消息创建一个缓存列表 
        this.clientList[key] = [];
    }
    // 将订阅消息添加进消息缓存列表
    this.clientList[key].push(fn);
  },
  // 发布消息
  trigger(...args){
    let key = args.shift(),
        fns = this.clientList[key];
    if( !fns || fns.length === 0 ){ //没有绑定对应消息
        return false;
    }
 
    for(let fn of fns){  //通知订阅该消息的所有订阅者
        fn.call(this,args); //args是trigger时带上的参数
    }
 
  },
  // 取消订阅
  remove(key,fn){
      let fns = this.clientList[key];
      if(!fns){
          return false;  //key对应的消息没有被人订阅,直接返回
      }
      if(!fn){ //没有传入fn,则表示取消key对应消息的所有订阅
          fns && ( fns.length=0 )
      }else{
        let index = fns.findIndex(function(val){
            return val===fn;
        });
        fns.splice(index,1); //删除订阅者的回调函数
        console.log('success');
      }
  }
};
 
Event.listen('88',price=>console.log('price='+price));
Event.trigger('88',88888);
 
// 模块间通信,每次点击a模块里面的按钮,b模块显示按钮点击次数
// 将b订阅的事件添加到全局发布--订阅对象
let b=(()=>{
  let div = document.getElementById('show');
  Event.listen('add',count => div.innerHTML=count );
})()
// 通过a触发全局发布--订阅对象发布消息
let a = (()=>{
  let count = 0;
  let button = document.getElementById('count');
  button.addEventListener('click',()=>Event.trigger('add',count++))
})()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59

上面利用全局发布–订阅对象实现模块间通信

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/42891
推荐阅读
相关标签
  

闽ICP备14008679号