代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

代理模式分类很多,应用场景也很多,本文主要讲述在js开发中最常用的虚拟代理和缓存代理。

虚拟代理

虚拟代理实现图片预加载


var realImg=(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 () {
        realImg.setSrc(this.src);
    }
    return {
        setSrc:function (src) {
            realImg.setSrc('loading.gif');
            img.src=src;
        }
    }
})();
proxyImage.setSrc("big.png");

将职责拆分,符合面向对象的单一职责原则。但是通常我们会将预加载和设置图片src逻辑都放到realImg中(demo),但是这样做违反设计模式的基本原则,以后网速快了,可能就不需要预加载,需要修改较多代码,维护性不好。

虚拟代理合并http请求

这个在web版本toList中或者文件列表勾选自动保存可以应用,防止手速过快频繁请求,节省带宽,前提是这些http接口具有一致性。


var  synchronousFile=function (id) {
    console.log('开始同步文件,id为 '+id);
}
var proxySynchronousFile=(function () {
    var cache=[],//保存待合并发送请求的id
        timer;
    return function (id) {
        cache.push(id);
        if(timer){
            return;
        }
        timer=setTimeout(function () {
            synchronousFile(cache.join(','));
            clearTimeout(timer);
            timer=null;
            cache.length=0;//按时间段重新初始化
        },2000)
    }
})();


var chkboxs=document.getElementsByTagName('input');
for(var i=0,len=chkboxs.length;i<len;i++){
    chkboxs.onclick=function () {
        if(this.checked=true){
            proxySynchronousFile(this.id);
        }
    }
}

缓存代理

缓存代理进行计算


var mult=function () {
    var tmp=1;
    for(var i=0;i<arguments.length;i++){
        tmp=tmp*arguments[i];
    }
    return tmp;
}
var plus=function () {
    var tmp=0;
    for(var i=0;i<arguments.length;i++){
        tmp=tmp+arguments[i];
    }
    return tmp;
}

var createProxyFactory=function (fn) {
    var cache={};
    return function () {
        var args=Array.prototype.join.call(arguments,',');
        if(args in  cache){
            return cache[args];
        }
        return cache[args]=fn.apply(this,arguments);
    }
}
//函数参数,根据需求,动态灵活的创建带缓存的计算方法
var proxyMult=createProxyFactory(mult),
    proxyPlus=createProxyFactory(plus);
console.log(proxyMult(2,3));
console.log(proxyMult(2,3));
console.log(proxyPlus(2,3));
console.log(proxyPlus(2,3));

适应一些开销大,重复步骤较多的场景。一定要结合具体业务场景分析,进行调优,上面其实也只是演示而已。


jsdt
4.9k 声望3.9k 粉丝

make a little progress every day