前端做接口缓存并统一管理
因为最近做的产品看的数据是历史数据,也就是说请求多次参数一样返回结果都一样,为了切换页面时loading少一点,做了缓存。开始的方案是将缓存写在当前页面,发现代码量太多,不好一次性清空缓存,于是想到了统一管理
需求:接口缓存,可一次清除缓存,可缓存可不缓存,代码量小。
思路:
- 存数据、统一管理:定义一个数组cacheData
- 一次清空:cacheData = []
- 可缓存可不缓存: 定义一个参数(isCache)来判断
- 考虑到前端都做了请求封装: 可以在封装的方法前加个中间层来判断是否要取缓存中的数据(requestCacheWrapper)
实现:
request.ts
interface CacheDataItem {
apiDataString: string
data: any
}
// 缓存数据存在这里
let cacheData:Array<CacheDataItem> = []
// 缓存数据上限 总览页和活动页不包括表格排序时大概缓存60个接口数据
const cacheDataMaxLength:number = 100
// 清空缓存
export const wipeCache = () => {
cacheData = []
}
// 获取缓存数据index
const getCacheIndex = (apiDataString, cacheData) => {
if (cacheData.length === 0) {
return -1
}
return cacheData.findIndex(item => {
return item.apiDataString === apiDataString
})
}
...
if (statusCode == 200 && data.code == 0) {
if (o.isCache) { // 缓存数据
cacheData.push({
apiDataString: getApiDataString(api,oData), // 不直接取o.data是因为get请求时formatRequestParams把o.data转化了
data
})
if (cacheData.length > cacheDataMaxLength) {
cacheData.shift()
}
}
return Promise.resolve(data)
}
...
// 获取api和请求参数转字符串后的字符串集合
const getApiDataString = (api, data) => {
data && delete data['_']
return `${api}${JSON.stringify(data)}`
}
// 判断是否要取缓存
const requestCacheWrapper = async (api, o: RequestOptions, options?: AuthRequestExtensionOptions) => {
if (o.isCache) {
let apiDataString = getApiDataString(api, o.data)
let cacheIndex = getCacheIndex(apiDataString,cacheData)
if (cacheIndex !== -1) {
// 取完数据后让数据在数组最后一位(经常用的数据放在数组末尾防止删除)
let resData = cacheData.splice(cacheIndex, 1)
cacheData.push(resData[0])
return resData[0].data
} else {
return request(api, o, options)
}
} else {
return request(api, o, options)
}
}
api
export const getData = (data, isCache: boolean = false) => {
return request('/data/getdata', {
method: 'POST',
data,
isCache
})
}
接口调用
getData(data, true)