代理模式
代理模式主要是为真正的对象提供一个替代品,以便控制外界对这个对象的访问。
代理模式按照使用目的可以划分为很多种类型:比如远程代理、缓存代理、保护代理、虚拟代理、同步代理等等,在 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>
如有错误,欢迎指正,本人不胜感激。