问题
在一个项目中,通过查看网络请求,发现同一时间(比如页面加载)很多相同请求,请求url相同,参数相同!这样无疑给后端增加了不必要的负担。
于是于是,就简单的想了下这些请求是否能进行合并啦?
网络请求合并
简单分析,项目中网络请求使用的axios库。既然是在同一时间,那么首先想到的就是防抖。
开干。
// 延时,如果发现相同请求地址、请求参数,则不重复请求 仅计入callback队列中
// 当前请求队列
const reqList = []
function mergeRequest(url, body, callback){
// 找是否有相同请求。中间对于 Object 对象的比较,是每个键、值都进行比较,包括数组值、对象值遍历深度比较
let found = reqList.find(item => item.url === url && valueEqual(item.body, body))
// 没找到,产生一个新请求缓存
if (!found){
found = {
url,
body: body,
callback: [callback],
timer: null,
idx: reqList.length
}
reqList.push(found)
} else {
// 仅把 结果处理函数放进
found.callback.push(callback)
}
// 清除计时器
found.timer && clearTimeout(found.timer)
// 记录计时器,
found.timer = setTimeout(() => {
axios.post(found.url, found.body)
.then(res => {
// 弹出
const [req] = reqList.splice(reqList.findIndex(item => item === found), 1)
for(const cb of req.callback){
cb.call(this, res)
}
})
}, 200)
}
下策
为什么说它是下策?
因为在正常的设计中,是不应该出现单请求被重复请求的情况。如果出现了,建议从设计层面去解决,文章中方法仅做对防抖、重复网络请求的一种变相思考。