美文网首页
代理模式

代理模式

作者: 池鱼_故渊 | 来源:发表于2021-01-19 23:27 被阅读0次

    代理模式

    定义:为一个对象提供一个代用品和占位符,以便控制对它的访问

    常用的虚拟代理模式:某个花销很大的操作,可以通过虚拟代理的方式延迟到需要创建的时候才去创建 (函数的节流防抖也是一种代理模式)
    例如:使用虚拟代理实现图片的懒加载
    图片的懒加载的方式:先通过一张 loading 图占位符,然后通过异步的方式加载图片,等待图片加载好,再把加载好的图片放到标签里面

    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 () {
        myImage.setSrc(img.src);
      };
      return {
        setSrc: function (src) {
          img.src = src; // 当图片加载完成时会触发 上面的img.onload 然后替换掉图片
          myImage.setSrc("loading图片地址");
        },
      };
    })();
    
    proxyImage.setSrc("图片地址");
    

    代理的意义是什么:单一职责原则(一个对象只有一个职责,如果一个对象担任过多的职责,那么这个对象将会不可控,代码就会变的很脆弱 )

    再看一个例子:虚拟代理合并 HTTP(取自 js 设计模式与开发实践)

    
    <body>
      <div id="wrapper">
        <input type="checkbox" id="1"></input>1
        <input type="checkbox" id="2"></input>2
        <input type="checkbox" id="3"></input>3
        <input type="checkbox" id="4"></input>4
        <input type="checkbox" id="5"></input>5
        <input type="checkbox" id="6"></input>6
        <input type="checkbox" id="7"></input>7
        <input type="checkbox" id="8"></input>8
        <input type="checkbox" id="9"></input>9
      </div>
    </body>
    
    <script type="text/javascript">
      // 模拟http请求
      var synchronousFile = function (id) {
        console.log('开始同步文件,id 为: ' + id);
      };
    
      var inputs = document.getElementsByTagName('input')
      var wrapper = document.getElementById('wrapper')
      wrapper.onclick = function (e) {
        if (e.target.tagName === 'INPUT' && e.target.checked) {
          proxySynchronousFile(e.target.id)
        }
      }
      var proxySynchronousFile = (function () {
        var cacheIds = [], // 缓存id
          timeId = 0 //定时器
        return function (id) {
          if (cacheIds.indexOf(id) < 0) {
            cacheIds.push(id)
          }
          clearTimeout(timeId)
          timeId = setTimeout(() => {
            synchronousFile(cacheIds.join(',')) //调用函数
            cacheIds = []
          }, 1000)
        }
      })()
    </script>
    

    通过代理缓存要发送的请求,最后统一发送请求
    实际上上面的函数就是一个函数防抖(所以说防抖节流也是一种代理模式)
    看过这几种模式是不是觉得设计模式也并不是很难懂的东西,但是如何使用设计模式,什么地方该用什么样的设计模式是需要一定的积累和应用的
    一种大家几乎都使用过的代理模式:事件代理

    <ul id="ul">
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
    </ul>
    <script>
        let ul = document.querySelector('#ul')
        ul.addEventListener('click', (event) => {
            console.log(event.target);
        })
    </script>
    

    因为存在太多的 li,不可能每个都去绑定事件。这时候可以通过给父节点绑定一个事件,让父节点作为代理去拿到真实点击的节点。

    相关文章

      网友评论

          本文标题:代理模式

          本文链接:https://www.haomeiwen.com/subject/hclhzktx.html