Appearance
虚拟代理合并 HTTP 请求
假设我们在做一个文件同步的功能,当我们选中一个 checkbox 的时候,它对应的文件就会被同 步到另外一台备用服务器上面,
html
<body>
<div id="proxy">
<input type="checkbox" id="1" />1
<input type="checkbox" id="2" />2
<input type="checkbox" id="3" />3
<input type="checkbox" id="4" />4
<input type="checkbox" id="5" />5
<input type="checkbox" id="6" />6
<input type="checkbox" id="7" />7
</div>
<script>
proxy.addEventListener('click', (e) => {
const { target } = e
if (target.checked) {
synchronousFile(target.id)
}
})
const synchronousFile = (id) => {
// request...
console.log(id)
}
</script>
</body>当我们选中 3 个 checkbox 的时候,依次往服务器发送了 3 次同步文件的请求。而点击一个 checkbox 并不是很复杂的操作,我们可以在 1s 内点击多个,如此频繁的网络请求将会带来相当 大的开销。解决方案是,我们可以通过一个代理函数 proxySynchronousFile 来收集一段时间之 内的请求,最后一次性发送给服务器。比如我们等待 2 秒之后才把这 2 秒之内需要同步的文件 ID 打包发给服务器,如果不是对实时性要求非常高的系统,2 秒的延迟不会带来太大副作用,却 能大大减轻服务器的压力。
javascript
proxy.addEventListener('click', (e) => {
const { target } = e
if (target.checked) {
proxySynchronousFile(target.id)
}
})
const synchronousFile = (ids) => {
// request...
console.log(ids.slice())
}
const proxySynchronousFile = (function () {
let ids = []
let timer = null
return function (id) {
ids.push(id)
if (!timer) {
timer = setTimeout(() => {
synchronousFile(ids)
clearTimeout(timer)
timer = null
ids = []
}, 2000)
}
}
})()