最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 『面试的底气』—— 设计模式之发布-订阅模式(三)|8月更文挑战

    正文概述 掘金(红尘炼心)   2021-08-18   515

    这是我参与8月更文挑战的第17天,活动详情查看:8月更文挑战

    前言

    在面试高级前端时,往往会遇到一些关于设计模式的问题,每次都回答不太理想。恰逢8月更文挑战的活动,准备用一个月时间好好理一下关于设计模式方面的知识点,给自己增加点面试的底气。

    在上篇文章 中实现了一个简单的发布-订阅模式,但是其中有两个很严重的缺点,每个发布者都要有添加订阅者 、发布消息、移除订阅者的方法,还要需要一个缓存订阅者的列表,这样严重浪费内存资源,另外一个是订阅者要知道发布者才能订阅,它们之间存在一定的耦合性。

    所以发布者和订阅者之间得需要一个中介,本文就来实现这个中介,这样发布者可以不必拥有添加订阅者 、发布消息、移除订阅者的方法、缓存订阅者的列表,把这些都交给中介。订阅者不需要了解消息来自哪个发布者,发布者也不知道消息会推送给哪些订阅者,中介会把订阅者和发布者联系起来。

    基于中介的发布-订阅

    var Event = (function () {
      let clientList = {};// 缓存订阅者列表
      const listen = function (key, fn) {// 添加订阅者 其中key为订阅者的标识
        if (!clientList[key]) {
          clientList[key] = [];
        }
        clientList[key].push(fn);
      };
      const trigger = function () { 
        // 通过`trigger`发布方法的第一参数来获取订阅者的标识
        const key = Array.prototype.shift.call(arguments);
        const fns = clientList[key];
        if (!fns || fns.length === 0) {
          return false;
        }
        for (let i = 0, fn; fn = fns[i++];) {
          fn.apply(this, arguments);
        }
      };
      const remove = function (key, fn) {
        const fns = clientList[key];
        if (!fns) {
          return false;
        }
        if (!fn) {
          fns && (fns.length = 0);
        } else {
          for (let l = fns.length - 1; l >= 0; l--) {
            const _fn = fns[l];
            if (_fn === fn) {
              fns.splice(l, 1);
            }
          }
        }
      };
      return {
        listen: listen,
        trigger: trigger,
        remove: remove
      }
    })();
    

    订阅者通过Event.listen来订阅消息:

    Event.listen('土豪金', function (price) { // 小王订阅消息
      console.log(`手机到货了,颜色是土豪金,价格是${price}元,快来购买吧!`) 
    });
    

    发布者通过Event.trigger来发布消息:

    Event.trigger('土豪金', 9999); // 输出:手机到货了,颜色是土豪金,价格是9999元,快来购买吧!
    

    JavaScript中的发布-订阅模式

    在JavaScript中,可以用注册回调函数的形式来简单地实现的发布-订阅模式,假如用类的方式来实现发布-订阅模式,还要把订阅者对象传入发布者对象中,同时订阅者对象还要提供一个更新 updata 的方法,供发布者在某个时候调用。

    另外发布-订阅模式,还有推模型还是拉模型的区分,推模型是指在事件发生时,发布者一次性把所有更改的状态和数据都推送给订阅者。拉模型是指发布者仅仅通知订阅者我已经发布了,提供一些公开的接口供订阅者来主动拉取数据,模型的好处是可以让订阅者按需获取信息。

    而在JavaScript中,arguments可以很方便地表示函数所接收的参数,所以在JavaScript中一般都会选择推模型,使用apply方法把所有参数都推送给订阅者。

    优点和缺点

    发布-订阅模式的优点非常明显,一为时间上的解耦,二为对象之间的解耦。

    发布-订阅模式也有缺点,创建订阅者本身要消耗一定的时间和内存,而且当你订阅一个消息后,也许此消息最后都未发生,但这个订阅者会始终存在于内存中。另外,发布—订阅模式虽然可以弱化对象之间的联系,但如果过度使用的话,对象和对象之间的必要联系也会被隐藏起来,当多个发布者和多个订阅者互相关联时,出现BUG将会很难跟踪和修复。


    起源地下载网 » 『面试的底气』—— 设计模式之发布-订阅模式(三)|8月更文挑战

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元