背景:项目中因为开发的时候没有使用防抖节流进行接口访问控制,导致正式上线运行的时候同一个请求调用多次。因为项目体量较大,逐个接口去改风险太大,成本较高,所以最终决定在真正调用axios的地方进行方法代理。
// 对axios的封装
const http = {
get(url,params){
return axios.get(`${url}`, {
params: params
})
}
}
/**
* 请求过滤器,减少重复的请求
*/
const requestFilter = {
requests: {},// 存储所有的request的promise
wrapped: (args, targetFun) => {
let targetPromise = undefined;
let md5 = undefined;
const _args = [];
if (args) {
// 将arguments 转换成为json 然后获取校验码
for (let i = 0; i < args.length; i++) {
_args.push(args[i]);
}
// 这里可以通过使用md5进行签名,生成一个短一点的键
md5 = JSON.stringify(_args);
targetPromise = requestFilter.requests[md5];
}
if (!targetPromise) {
targetPromise = targetFun.call(http, ..._args);
if (md5) {
requestFilter.requests[md5] = targetPromise;
}
}
return new Promise((resolve, reject) => {
targetPromise.then(resp => {
resolve(resp);
}).catch(err => {
reject(err);
}).finally(() => {
setTimeout(() => {
delete requestFilter.requests[md5];
}, 0);
});
})
;
}
};
// 需要增强的函数名称
const wrappedFuns = ["get"];
wrappedFuns.forEach(funName => {
const _fun = http[funName];
http[funName] = function() {
return requestFilter.wrapped(arguments, _fun);
};
});