代理模式
原理
客户 ==> 代理 ==> 本体
是不是很像如下:
客户端 ==> nginx ==> 服务器
代理模式: 是为一个对象提供一个替代品,准确说是占位符, 用来控制它的访问.
尤其这个对象是一些性能开销很大的对象, 该种代理叫做虚拟代理.
虚拟代理: 把一些开销很大的对象延迟到需要它的时候才创建.
虚拟代理举例说明
- 图片懒加载
在某些拥有大量图片的页面(电商尤为常见), PC端常用的一种技术叫做图片懒加载(移动端尤其).原理这里就不做介绍了.
主要说下图片懒加载下的虚拟代理实现.
<!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>
</body>
<script>
window.onload = function () {
// 图片懒加载函数
const myImage = (function (src) {
let imgNode = document.createElement('img')
document.body.appendChild(imgNode)
return {
setSrc (src) {
imgNode.src = src
}
}
})()
// 代理对象
const proxyImage = (function () {
const img = new Image();
img.onload = function () {
// 加载真正的图片
myImage.setSrc(this.src)
}
return {
set (url) {
myImage.setSrc('./1.jpeg') // 本地的loading图片
img.src = url
}
}
})()
setTimeout(() => {
proxyImage.set('https://publish-pic-cpu.baidu.com/4d09f82c-db73-468c-8e5f-9656876891f2.jpeg@f_webp,q_90,w_230')
}, 5000)
}
</script>
</html>
上述懒加载功能当然可以直接写在一个函数里面实现:
但是使用代理, 有如下一些好处:
- 细粒度化: 函数各司其职,单一职责原则.
- 降低耦合.方便后期维护或者扩展.
缓存代理
缓存代理: 多用于大量数据计算时候,或者存储时候.为了避免不必要的重复计算,我们可以使用缓存代理,提升代码的性能.减少代码执行时间.
下述以一个计算加法的例子描述缓存代理的使用.
// 处理计算的函数: 求数组中元素的和
const sum = (list) => list.reduce((v, i) => v + i, 0)
// 代理对象
const proxySum = (function () {
// 缓存对象
var cache = {}
return function () {
// 已缓存的标识符
let flag = Array.prototype.join.call(arguments, '-')
if (flag in cache) {
// 返回缓存
console.log('返回缓存数据')
return cache[flag]
}
console.log('第一次计算')
return cache[flag] = sum.apply(this, arguments)
}
})()
console.log(proxySum([1,2,3,4,5,6,7,8,9,10])) // 第一次计算 55
console.log(proxySum([1,2,3,4,5,6,7,8,9,10])) // 返回缓存数据 55