公共数据缓存调用
工具方法:
新建一个类,全局一个实例,暴露方法:getCacheDataByKey
- 1 先判断传过来的keyList 是否在可支持列表中
- 2 判断是否有缓存值,如果没有缓存直接进入第3步,如果有缓存,筛选中未缓存的key
- 3 根据key,选择相应的策略,调用相应的接口,更新缓存
- 4 从缓存中取keyList 需要的所有值
优势:进入下个页面,无需调用接口,刷新后,可重新调用接口
特殊说明:
- 传过来的参数key,可以是单个str,或者 字符串列表,可以避免每个key都需要跑一遍函数
- 缓存 cache 是个对象
- 最终取值是从cache中取,返回给调用方的是 对象
import * as service from './service';
export const commonDataKeys = {
OWNED_GROUP_DATA: 'ownedGroupData',
APPLICATION_LIST: 'applicationList',
};
export class CommonDataCacheProxy {
constructor() {
this.cache = {};
}
/**
* 检查请求的数据列表是否可用
* @param reqKeyList {string | string[]} 请求的公共数据的Key值列表
* @returns {string[]} 可用的公共数据的Key值列表
*/
checkReqKeyList = (reqKeyList) => {
if (!Array.isArray(reqKeyList) && typeof reqKeyList === 'string') reqKeyList = [reqKeyList];
if (!Array.isArray(reqKeyList)) throw new TypeError('参数reqKeyList不为Array或String');
const invalidateKey = reqKeyList.find((key) => Object.values(commonDataKeys).every((itm) => itm !== key));
if (invalidateKey) throw new Error(`不存在的commonDataKey: ${invalidateKey}`);
return reqKeyList;
}
/**
* 筛选出未缓存的Key值列表
* @param reqKeyList {string[]} 请求公共数据Key值列表
* @returns {string[]} 未缓存的公共数据Key值列表
*/
filterUncachedKeyList = (reqKeyList) => {
const { cache } = this;
if (Object.keys(cache).length === 0) return reqKeyList;
return reqKeyList.filter((key) => !(cache[key] && cache[key].length > 0));
};
/**
* 从缓存中取出请求的公共数据
* @param reqKeyList {string[]} 请求公共数据Key值列表
* @returns {Object} 返回的公共数据
*/
extractCachedCommonData = (reqKeyList) => {
const { cache } = this;
return reqKeyList.reduce((acc, key) => {
acc[key] = cache[key]
return acc;
}, {});
};
fetchDataPromise = (key) => {
const plan = {
[commonDataKeys.OWNED_GROUP_DATA]: () => (
service.loadOwnedGroupList().then(({ data }) => ({
[commonDataKeys.OWNED_GROUP_DATA]: [data],
}))
),
[commonDataKeys.APPLICATION_LIST]: () => (
service.loadApplicationList().then(({ data }) => {
const format = (list) => list?.map((application) => (
{
label: application,
value: application,
}
));
return {
[commonDataKeys.APPLICATION_LIST]: format(data),
};
})
),
};
return plan[key]();
}
/**
* 从服务端请求未缓存的公共数据
* @param uncachedKeyList {string[]} 待请求的公共数据的Key值列表
*/
requestUncachedData = async (uncachedKeyList) => {
const fetchDataList = await Promise.all(uncachedKeyList.map((reqKey) => (this.fetchDataPromise(reqKey))));
const fetchDataMap = fetchDataList.reduce((result, item) => Object.assign(result, item), {});
const { cache } = this;
this.cache = {
...cache,
...fetchDataMap,
};
};
getCommonData = async (reqKeyList) => {
const reqKeys = this.checkReqKeyList(reqKeyList);
const uncachedReqKeyList = this.filterUncachedKeyList(reqKeys);
if (uncachedReqKeyList.length === 0) return this.extractCachedCommonData(reqKeys);
await this.requestUncachedData(uncachedReqKeyList);
return this.extractCachedCommonData(reqKeys);
};
}
const cacheProxy = new CommonDataCacheProxy();
export const getCacheDataByKey = cacheProxy.getCommonData;
使用方法:
dispatch({ type: 'queryCommonData', payload: [commonDataKeys.APPLICATION_LIST] });
...
* queryCommonData({ payload }, { call, put }) {
const commonData = yield call(getCacheDataByKey, payload);
yield put({ type: 'applyReduce', payload: { ...commonData } });
},
// commonData { applicationList: [...] }
分页数据也可参考此思想