代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式分类很多,应用场景也很多,本文主要讲述在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));
适应一些开销大,重复步骤较多的场景。一定要结合具体业务场景分析,进行调优,上面其实也只是演示而已。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。