代理模式
男主 =》 女主闺蜜 =》 女主
找对象:男主 需要通过 女主闺蜜 传递消息给 女主(并监听女主心情的变化)
代理模式作用及分类
保护代理
女主闺蜜:既要保护男主利益(传递消息),也要保护女主利益(访问控制:只要高富帅)
虚拟代理
送玫瑰
男主送给玫瑰花给女主
- 送玫瑰(错误):男主提前买玫瑰花=》女主闺蜜 =》女主(花枯萎)
- 送玫瑰(正确:懒得执行):女主闺蜜(看时机买玫瑰花) =》给女主(花新鲜)
文件同步
勾选按钮后上传文件到服务器
<body>
<input type="checkbox" id="1" />
<input type="checkbox" id="2" />
<input type="checkbox" id="3" />
...
</body>
const synchronousFile = function (id) {
console.log(`开始同步文件,id为:${id}`);
};
const checkbox = document.getElementByTagName("input");
for (let i = 0; i < checkbox.length; i++) {
const c = checkbox[i];
c.onclick = function () {
if (this.checked === true) {
synchronousFile(this.id);
}
};
}
优化后代码:
const synchronousFile = function (id) {
console.log(`开始同步文件,id为:${id}`);
};
const proxySynchronousFile = (function () {
const ceche = []; //保存一段时间内需要同步的ID
const timer// 定时器
return function(id){
cache.push(id)
if( timer ){ // 保证不会覆盖已经启动的定时器
return
}
timer = setTimeout(function(){
synchronousFile(ceche.join(',')) // 2秒后向服务器发送需要同步的ID集合
clearTimeout(timer) // 清除定时器
timer = null
cache.length = 0 // 清空ID集合
},2000)
}
})();
const checkbox = document.getElementByTagName("input");
for (let i = 0; i < checkbox.length; i++) {
const c = checkbox[i];
c.onclick = function () {
if (this.checked === true) {
proxySynchronousFile(this.id)
}
};
}
生活中案例 快递员、信使
缓存代理
累乘 复杂计算结果缓存
var mult = function () {
console.log("开始计算累乘");
let a = 1;
for (let i = 0; i < arguments.length; i++) {
a = a * arguments[i];
}
return a;
};
mult(2, 3); // output:6
mult(2, 3, 4); // output:24
计算mult(2, 3, 4)
时mult(2, 3)
已经计算过,会造成多余计算
优化后代码:高阶函数
var proxyMult = (function () {
var cache = {};
return function () {
var args = Array.prototype.join.call(arguments, ",");
if (args in cache) {
return cache[args];
}
return (cache[args] = mult.apply(this, arguments));
};
})();
proxyMult(1, 2, 3, 4); // output :24
proxyMult(1, 2, 3, 4); // output :24
ES6 Proxy:斐波那契
const getFib = (number) => {
if (number <= 2) {
return 1;
} else {
return getFib(number - 1) + getFib(number - 2);
}
};
以上代码想象成 复杂逻辑 优化后:
const getFib = (number) => {
if (number <= 2) {
return 1;
} else {
return getFib(number - 1) + getFib(number - 2);
}
};
const getCacheProxy = (fn, cache = new Map()) => {
return new Proxy(fn, {
// 声明(缓存)代理
apply(target, context, args) {
const argsString = args.join(" ");
if (cache.has(argsString)) {
// 如果有缓存,直接返回缓存数据
return cache.get(argsString);
}
const result = fn(...args);
// 存入Map中
cache.set(argsString, result);
return result;
},
});
};
const getFibProxy = getCacheProxy(getFib);
getFibProxy(40); // output 40