手记

代理模式

代理模式

代理模式主要是为真正的对象提供一个替代品,以便控制外界对这个对象的访问。
代理模式按照使用目的可以划分为很多种类型:比如远程代理、缓存代理、保护代理、虚拟代理、同步代理等等,在 JavaScript 中,使用频率较高的当属缓存代理和虚拟代理。

缓存代理

为一些开销较大的运算结果提供临时的储存空间,以便可以共享这些结果。

使用场景

比如我们经常遇到的分页,理想的效果一定是:同一页的数据只需从后台请求一次,再次点击该页的时候,会直接使用缓存的数据。

例子:

<style>
    ul {
        display: flex;
        flex-direction: row;
        padding-left: 0;
    }

    ul li {
        list-style: none;
    }
</style>

<table>
</table>
<ul>
    <li>
        <button id="page01" onclick="proxyFn(event)">1</button>
    </li>
    <li>
        <button id="page02" onclick="proxyFn(event)">2</button>
    </li>
</ul>

<script>
    var creatDom = function (list) {
        document.querySelector("table").innerHTML = " ";
        list.slice(0, 2).forEach(function (v) {
            var _dom = document.createElement("tr");
            _dom.innerHTML = v;
            document.querySelector("table").appendChild(_dom);
        });
    }
    var proxyFn = (function (e) {
        // 创建代理 data,用以缓存数据
        var data = {};
        return function (e) {
            // 如果有缓存数据,则直接使用
            if (data[e.currentTarget.id]) {
                creatDom(data[e.currentTarget.id]);
                console.log("使用缓存数据!");
                return;
            }
            // 第一次请求后台数据
            // 更新页面并存入缓存代理
            var _arr = [];
            for (var i = 0; i < 10000; i++) {
                _arr.push(Math.ceil(Math.random() * 10) + i);
            }
            creatDom(_arr);
            data[e.currentTarget.id] = _arr;
        }
    })();
</script>

虚拟代理

由代理去创建一些开销较大的对象,而真正的对象将延迟创建。

使用场景

比如现在的很多应用都会收集用户的浏览信息,以便有针对性的提供商品。
但如果用户每选中一个多选框,就会向服务器发送请求,如此频繁的网络请求一定会带来巨大的开销,理想的解决方法是:收集一段时间内的请求,统一发送给服务器。

例子:

<style>
    ul {
        display: flex;
        flex-direction: row;
        padding-left: 0;y
    }

    ul li {
        list-style: none;
    }
</style>

<ul>
    <li><input type="checkbox" value="衣服">衣服</li>
    <li><input type="checkbox" value="玩具">玩具</li>
</ul>
<ul>
    <li><input type="checkbox" value="衣服">衣服</li>
    <li><input type="checkbox" value="玩具">玩具</li>
</ul>
<ul>
    <li><input type="checkbox" value="衣服">衣服</li>
    <li><input type="checkbox" value="玩具">玩具</li>
</ul>

<script>
    var domList=[...document.querySelectorAll("input[type=checkbox]")];
    domList.forEach(function(v){
        v.addEventListener("click",function(){
            if(v.checked===true){
                proxyFn(v.value);
            }
        });
    });
    var proxyFn = (function () {
        // 创建代理,以便合并多个HTTP请求
        var data=[],timer;
        return function(value){
            data.push(value);
            // 如果用户多次点击,保证只执行一次定时器
            if(timer){
                return;
            }
            // 每隔两秒钟,向服务器发送一次请求
            timer=setTimeout(function(){
                console.log("向服务器发送:"+data.join());
                data=[];
                clearTimeout(timer);
                timer=null;
            },3000);
        }
    })();
</script>

如有错误,欢迎指正,本人不胜感激。

0人推荐
随时随地看视频
慕课网APP