代理模式
解决哪一类问题
从字面意思上理解,代理模式解决对一个对象的直接访问,这种直接访问可能是"不方便"的,所谓"不方便"可能是直接访问成本比较大(在前端领域通常是要获取后台数据或者执行复杂的计算),或者需要对原始对象进行一些修饰或处理。
实现原理
实现一个代理对象,这个代理对象和原对象对外暴露相同的接口,用户直接操作代理对象,对于说对用户是透明的,用户并不知道有代理存在。
虚拟代理
把一些昂贵的操作放在代理对象中进行,现在体会的还不是很深刻,具体例子没想好,以后补充。
缓存代理
把昂贵操作产生的数据缓存在代理对象中,避免了重复操作
// 假设a*b是个昂贵的操作
function calculate(a, b) {
return a*b
}
var proxyCalculate = (function() {
var cache = {}
return function(a, b) {
var ab = '' + a + '_' + b
if (ab in cache) {
return cache[ab]
}
return cache[ab] = calculate(a, b)
}
})()
var a = 99999, b = 99999
proxyCalculate(a, b)
实践中的应用
利用代理来做节流操作
直接copy书上的代码
假设我们在做一个文件同步的功能,当我们选中一个 checkbox 的时候,它对应的文件就会被同 步到另外一台备用服务器上面,当我们选中 3 个 checkbox 的时候,依次往服务器发送了 3 次同步文件的请求,
可以预见,如此频繁的网络请求将会带来相当大的开销。
<body>
<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
</body>
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; // 清空 ID 集合
}, 2000 );
}// 2 秒后向本体发送需要同步的 ID 集合
})();
var checkbox = document.getElementsByTagName( 'input' );
for ( var i = 0, c; c = checkbox[ i++ ]; ){
c.onclick = function(){
if (this.checked === true){
proxySynchronousFile( this.id );
}
}
}