console
// 缓存对象
let cache = {
// 缓存列表
list: [],
// 最大缓存数
MAX_NUM: 100,
// 最大缓存时间
EXPIRED_TIME: 60000,
// 根据请求的信息(请求方式,url,请求get/post数据),产生map的key
getRequestKey(config){
const { method, url, params, data } = config;
return [method, url, Qs.stringify(params), Qs.stringify(data)].join("&");
},
// 添加缓存结果
add({config, data}){
if(config.data) config.data = JSON.parse(config.data)
let key = this.getRequestKey(config)
let i = this.list.findIndex(t=>t.key === key)
if(i>-1){
// 保存请求结果
this.list[i].data = data
// 把结果给接口
this.list[i].resolve(data)
}else{
// 添加到缓存列表中
this.list.push({ time: Date.now(), key, data })
}
},
// 查找缓存结果
find(config){
// 根据请求信息生成key
let key = this.getRequestKey(config)
let i = this.list.findIndex(t=> t.key === key)
// 判断缓存当中是否有该请求结果
if(i>-1){
let f = this.list[i]
// 判断是否超出了最大缓存时间
if(Date.now() - f.time > this.EXPIRED_TIME){
// 清除该缓存
this.list.splice(i, 1)
}else{
// 返回缓存
return f
}
}
// 添加缓存信息
let t = {key, time: Date.now()}
t.data = new Promise((resolve)=>{
t.resolve = resolve
})
// 判断是否超出了最大缓存数量
if(this.list.length === this.MAX_NUM){
this.list.shift()
}
this.list.push(t)
// 返回undefined,让请求拦截不执行config.adapter
return undefined
}
}
let sendPost = function(data){
return axios({
url: 'http://nodejs-cloud-studio-demo-bkzxs.nodejs-cloud-studio-demo.50185620.cn-hangzhou.fc.devsapp.net/test',
method: 'post',
data
})
}
axios.interceptors.request.use(async function (config) {
let f = cache.find(config)
// 查看缓存当中有没有
if(f){
// 通过config.adapter,允许自定义处理请求
config.adapter = function (config) {
return new Promise((resolve) => {
const res = {
status: 200,
statusText: 'OK',
headers: { 'content-type': 'application/json; charset=utf-8' },
config,
request: {}
}
// 判断缓存当中data是否是Promise?
// 如果是,代表数据正在获取中
// 如果不是代表请求已经获取过
if(f.data instanceof Promise){
f.data.then(data=>{
resolve({ ...res, data })
})
}else{
resolve({ ...res, data: f.data })
}
})
}
}
return config
})
axios.interceptors.response.use(
(response) => {
//请求成功
//缓存结果到缓存中
cache.add(response)
return response;
}
);
new Vue({
el: '#app',
mounted() {
this.$refs.btn1.click()
this.$refs.btn2.click()
},
methods: {
// 使用lodash对请求方法做防抖
//这里有问题,只是对每个按钮的点击事件单独做了防抖,但是两个按钮之间做不到防抖的效果
onClick1: async function(){
let res = await sendPost({username:'zs', age: 20})
console.log('请求1的结果', res.data)
},
onClick2: async function(){
let res = await sendPost({username:'zs', age: 20})
console.log('请求2的结果', res.data)
},
},
})
<div id="app">
<button @click="onClick1" ref="btn1">请求1</button>
<button @click="onClick2" ref="btn2">请求2</button>
</div>