Skip to main content

代理模式

男主 =》 女主闺蜜 =》 女主

找对象:男主 需要通过 女主闺蜜 传递消息给 女主(并监听女主心情的变化)

代理模式作用及分类

保护代理

女主闺蜜:既要保护男主利益(传递消息),也要保护女主利益(访问控制:只要高富帅)

虚拟代理

送玫瑰

男主送给玫瑰花给女主

  • 送玫瑰(错误):男主提前买玫瑰花=》女主闺蜜 =》女主(花枯萎)
  • 送玫瑰(正确:懒得执行):女主闺蜜(看时机买玫瑰花) =》给女主(花新鲜)

文件同步

勾选按钮后上传文件到服务器

<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