关于前端:发布订阅者观察者模式以及-代理模式

8次阅读

共计 2029 个字符,预计需要花费 6 分钟才能阅读完成。

概念

它定义了对象一对多的关系,让多个观察者对象同时监听某一个主题。当依赖的对象产生扭转时候,所有依赖于他的对象,都会失去告诉

例子

  • 订购双十一购物车。收到短信提醒
  • 电话号码留在售楼部花名,订购售楼部收盘信息
  • vue-watch-computed& 观察者模式

长处

  • 反对简略的播送通信,当对象状态产生扭转时,会主动告诉曾经订阅过的对象。
  • 发布者与订阅者耦合性升高,发布者只管公布一条音讯进来,它不关怀这条音讯如何被订阅者应用,同时,订阅者只监听发布者的事件名,只有发布者的事件名不变,它不论发布者如何扭转

毛病

  • 创立订阅者须要耗费肯定的工夫和内存。如果适度应用的话,反而使代码不好了解及代码不好保护等等。
  • 比方咱们罕用的 events.

    import EventEmitter from 'events';
     EventEmitter.addListener('ResetjoblistNum', () => {
        this.pageNum = 1
        this.flag = true
      })
     
     EventEmitter.emit('ResetjoblistNum', '') 
      

实战

  • 给发布者增加一个缓存列表,用于寄存回调函数来告诉订阅者 (比方下面的买家珍藏了卖家的店铺,卖家通过珍藏了该店铺的一个列表名单)。
  • 最初就是公布音讯,发布者遍历这个缓存列表,顺次触发外面寄存的订阅者回调函数。
var Event = (function(){var list = {},
          listen,
          trigger,
          remove;
          listen = function(key,fn){if(!list[key]) {
                // 如果还没有订阅过此类音讯,给该类音讯创立一个缓存列表
                list[key] = [];}
            list[key].push(fn); // 订阅音讯增加到缓存列表
        };
        trigger = function(){var key = Array.prototype.shift.call(arguments), // 取出音讯类型名称
                 fns = list[key]; // 取出该音讯对应的回调函数的汇合
            // 如果没有订阅过该音讯的话,则返回
            if(!fns || fns.length === 0) {return false;}
            for(var i = 0, fn; fn = fns[i++];) {fn.apply(this,arguments); // arguments 是公布音讯时附送的参数
            }
        };
        remove = function(key,fn){
            // 如果 key 对应的音讯没有订阅过的话,则返回
            var fns = list[key];
            // 如果没有传入具体的回调函数,示意须要勾销 key 对应音讯的所有订阅
            if(!fns) {return false;}
            if(!fn) {fns && (fns.length = 0);
            }else {for(var i = fns.length - 1; i >= 0; i--){var _fn = fns[i];
                    if(_fn === fn) {fns.splice(i,1);// 删除订阅者的回调函数
                    }
                }
            }
        };
        return {
            listen: listen,
            trigger: trigger,
            remove: remove
        }
})();
// 测试代码如下:Event.listen("color",function(size) {console.log("尺码为:"+size); // 打印出尺码为 42
});
Event.trigger("color",42);

2. 代理模式

一个对象,跟本体对象具备雷同的接口,以达到对本地对象的访问控制
本地对象只重视业务逻辑的实现,代理管制本地对象的实例化。

简略的来说

  • 客户 - 主体
  • 客户 - 代理 - 主体

比方广告找明星代言,广告商只能分割他的经纪人,经纪人会把商业上演的细节和报酬谈好了,再把合同给到明星来签订

长处

  • 代理对象能够代替本体对象被实例化,此时本体对象未真正实例化,等到适合机会再实例化。
  • 指摘繁多
  • 虚构代理,把开销最大的对象,提早到真正须要它的时候再做创立
  • 爱护代理,AOP 切面思维,先做过滤,再做操作。
// 虚构代理
var myImage = (function () {var imgNode = document.createElement('img')
  document.body.appendChild(imgNode)
  return {setSrc: function (src) {imgNode.src = src},
  }
})()
// 代理模式
var ProxyImage = (function () {var img = new Image()
  img.onload = function () {setTimeout(() => {myImage.setSrc(this.src)
    }, 2000)
  }
  return {setSrc: function (src) {
      myImage.setSrc('http://img.lanrentuku.com/img/allimg/1212/5-121204193R0.gif')
      img.src = src
    },
  }
})()
export default ProxyImage
正文完
 0