代理模式
- What: 为一个对象提供一个代用品或占位符,以便控制对他的访问
- where: 图片预加载,合并http请求(上传、切换页面请求数据)、防火墙代理、远程代理、保护代理(权限)、写时复制代理
- when:
- who:
- why:
- how:
代理模式分类
- 保护代理:过滤无效请求。
- 虚拟代理:将一些开销很大的部分,延迟到需要时创建。
为什么使用代理
- 单一职责原则(功能分离,设置img和预加载分离),开放封闭原则(后期修改可分功能更改)。
- 代理和本体接口一致性(使用方无感知),后期去除用户无感知
应用实例
图片预加载
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
img {
width: 200px;
height: 200px;
border: 1px solid red;
}
</style>
</head>
<body>
<script>
// 图片预加载
var myImage = (function () {
var imgNode = document.createElement('img');
var dom = document.body;
dom.appendChild(imgNode);
return {
setSrc: function (src) {
imgNode.src = src;
}
}
})();
var proxyImage = (function () {
var img = new Image();
img.onload = function () {
myImage.setSrc(this.src);
};
return {
setSrc: function (src) {
var localImg = 'file:///Users/lixueyan01/Documents/myCode/proxy/2.jpeg';
myImage.setSrc(localImg); // 设置预加载图片
img.src = src;
}
}
})();
var img = 'https://upload-images.jianshu.io/upload_images/17067918-0e5ba09e3ba5d0e4.jpeg?imageMogr2/auto-orient/strip|imageView2/2/w/670/format/webp';
proxyImage.setSrc(img);
</script>
</body>
</html>
合并请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<input type="checkbox" id="1">1</input>
<input type="checkbox" id="2">2</input>
<input type="checkbox" id="3">3</input>
<input type="checkbox" id="4">4</input>
<input type="checkbox" id="5">5</input>
<input type="checkbox" id="6">6</input>
<input type="checkbox" id="7">7</input>
<script>
var synchronousFile = function(id) {
console.log('开始同步文件 id:' + id);
};
var proxySynchronousFile = (function() {
var cache = [];
var 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 checkbox = document.getElementsByTagName('input');
for (var i = 0, c; c = checkbox[i++];) {
c.onclick = function() {
if (this.checked === true) {
proxySynchronousFile(this.id);
}
};
}
</script>
</body>
</html>