美文网首页
javascript设计模式( 三)代理模式

javascript设计模式( 三)代理模式

作者: Sccong | 来源:发表于2017-08-03 16:22 被阅读0次

    代理模式,顾名思义,就是A要对C做一件事情,让B帮忙做(怎么听起来怪怪的)。

    // A
    var A = function(){
        this.talk = function(){
            console.log("能带我打dota2吗");
        }
    };
    //C
    var C= function(){
        this.B = new B();
        this.talk = function(){
            console.log("一个人打dota2好没意思啊");
            this.B.talk();
        }
    }
    //我
    var B = function(){
        this.A = new A();
        this.talk = function(){
            console.log("A 让我问你");
            this.A.talk();
        }
    }
    //执行
    new C().talk();
    //结果
    /**
     * 一个人打dota2好没意思啊
     * A 让我问你
     * 能带我打dota2吗
     */
    

    下面写几个常见的使用代理模式的例子

    在网页开发中,图片的预加载是一种比较常用的技术,如果直接给img标签节点设置src属性的话,如果图片比较大的话,或者网速相对比较慢的话,那么在图片未加载完之前,图片会有一段时间是空白的场景,这样对于用户体验来讲并不好,那么这个时候我们可以在图片未加载完之前我们可以使用一个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(this.src);
        };
        return {
            setSrc: function(src) {
                myImage.setSrc("http://img.lanrentuku.com/img/allimg/1212/5-121204193Q9-50.gif");
                img.src = src;
            }
        }
    })();
    
    // 调用方式
    ProxyImage.setSrc("https://img.alicdn.com/tps/i4/TB1b_neLXXXXXcoXFXXc8PZ9XXX-130-200.png");
    

    如上代码所示,其中myImage 函数只负责做一件事,创建img元素加入到页面中,其中的加载loading图片交给代理函数ProxyImage 去做,当图片加载成功后,代理函数ProxyImage 会通知及执行myImage 函数的方法,同时当以后不需要代理对象的话,我们直接可以调用本体对象的方法即可。
    代理模式还可以用在需要多次提交数据的地方,比如,有表格数据,每一条数据前面有复选框按钮,当点击复选框按钮时候,需要获取该id后需要传递给给服务器发送ajax请求,服务器端需要记录这条数据,去请求,如果我们每当点击一下向服务器发送一个http请求的话,对于服务器来说压力比较大,网络请求比较频繁,但是如果现在该系统的实时数据不是很高的话,我们可以通过一个代理函数收集一段时间内(比如说2-3秒)的所有id,一次性发ajax请求给服务器,相对来说网络请求降低了, 服务器压力减少了;

    // 本体函数
    var mainFunc = function(ids) {
        console.log(ids); // 即可打印被选中的所有的id
        // 再把所有的id一次性发ajax请求给服务器端
    };
    // 代理函数 通过代理函数获取所有的id 传给本体函数去执行
    var proxyFunc = (function(){
        var cache = [],  // 保存一段时间内的id
            timer = null; // 定时器
        return function(checkboxs) {
            // 判断如果定时器有的话,不进行覆盖操作
            if(timer) {
                return;
            }
            timer = setTimeout(function(){
                // 在2秒内获取所有被选中的id,通过属性isflag判断是否被选中
                for(var i = 0,ilen = checkboxs.length; i < ilen; i++) {
                    if(checkboxs[i].hasAttribute("isflag")) {
                        var id = checkboxs[i].getAttribute("data-id");
                        cache[cache.length] = id;
                    }
                }
                mainFunc(cache.join(',')); // 2秒后需要给本体函数传递所有的id
                // 清空定时器
                clearTimeout(timer);
                timer = null;
                cache = [];
            },2000);
        }
    })();
    var checkboxs = document.getElementsByClassName("j-input");
    for(var i = 0,ilen = checkboxs.length; i < ilen; i+=1) {
        (function(i){
            checkboxs[i].onclick = function(){
                if(this.checked) {
                    // 给当前增加一个属性
                    this.setAttribute("isflag",1);
                }else {
                    this.removeAttribute('isflag');
                }
                // 调用代理函数
                proxyFunc(checkboxs);
            }
    
        })(i);
    }
    

    缓存代理可以为一些开销大的运算结果提供暂时的存储,在下次运算时,如果传递进来的参数跟之前一致,则可以返回前面的运算结果。

    // 计算乘积
    var mult = function(){
        var a = 1;
        for( var i = 0, l = arguments.length; i < l; i++){
            a = a * arguments[i];
        }
        return a;
    };
    // 计算加和
    var plus = function () {
      var a = 0;
        for( var i = 0, l = arguments.length; i < l; i++ ){
            a += arguments[i];
        }
        return a;
    };
    // 创建缓存代理的工厂
    var createProxyFactory = function( fn ){
        var cache = {}; // 缓存 - 存放参数和计算后的值
        return function(){
            var args = Array.prototype.join.call(arguments, "-");
            if( args in cache ){ // 判断出入的参数是否被计算过
                console.log( "使用缓存代理" );
                return cache[args];
            }
            return cache[args] = fn.apply( this, arguments );
        }
    };
    // 创建代理
    var proxyMult = createProxyFactory( mult ),
        proxyPlus = createProxyFactory( plus );
    
    console.log( proxyMult( 1, 2, 3, 4 ) ); // 输出: 24
    console.log( proxyMult( 1, 2, 3, 4 ) ); // 输出: 缓存代理 24
    console.log( proxyPlus( 1, 2, 3, 4 ) ); // 输出: 10
    console.log( proxyPlus( 1, 2, 3, 4 ) ); // 输出: 缓存代理 10
    

    相关文章

      网友评论

          本文标题:javascript设计模式( 三)代理模式

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