promise缓存与缓存思想的总结
- JS单例模式
- 关于promise缓存
JS单例模式
单例模式,
保证一个类有且仅有一个实例
,并提供一个访问它的全局访问点
我们举个简单的例子
class SingletonFLX {
constructor(name, age) {
this.name = name;
this.age = age;
}
//静态方法
static getInstance(name, age) {
if(!this.instance) {
this.instance = new SingletonFLX(name, age);
}
return this.instance;
}
}
let flx = SingletonFLX.getInstance('flx', 25);
let cxy = SingletonFLX.getInstance('cxy', 23)
console.log(flx === cxy); //true
console.log(flx)
console.log(cxy)
关于缓存
- 缓存是计算机已经接收并使用过一次,然后保存以备将来使用的数据。
关于Map数据结构常见的用法
- 缓存数据:使用Map来缓存经常使用的数据,避免重复计算或请求,可以减少网络请求和计算时间,提高页面加载速度和响应速度。
关于promise缓存
问题来源:有一个子组件,mounted里面有一次网络请求。一个父页面使用50次这个子组件,那这个请求会发50次。我们实际需求是让它发一次就行
如何解决这个问题?
- 方式一:使用单例模式,完成缓存
// cache.js
// 缓存
const cache = null;
// 计数用
let count = 0;
// 等待时间用的函数
async function delay(ms = 200) {
return new Promise(resolve => setTimeout(resolve, ms));
}
export async function getData() {
// 计数
const myCount = count++;
// 第一步:如果缓存中有数据,就取缓存中的
if (cache) { return cache; }
// 第二步:如果不是第一次请求,就让等待
// 第一次是0
if (myCount!=0) {
while (!cache) {
await delay();
}
} else {
// 第三步:如果是第一次请求,就发远程请求
cache = await fetchData();
}
// 刷新 cache 的时候用
count--;
return cache;
}
- 方式二:使用Map缓存promise
const cacheMap = new Map();
// 一般来说,key用url+params拼接成
function generateCacheKey(config) {
return config.url + '?' + qs.stringify(config.params)
}
getData(){
// 通过URL,生产cacheKey
const cacheKey = generateCacheKey(URLConfig);
// 如果缓存中没有,创建promise且加入缓存中
if(!cacheMap.has(cacheKey)){
const myPromise = fetchData();
cacheMap.set(cacheKey, myPromise);
}
// 如果有的话,返回缓存中的
return cacheMap.get(cacheKey);
}
其实缓存就是种思想,如上面说的。可以用别的方式实现缓存,不一样非要用Map,当然推荐用Map。Map写起来比别的方便。
// 用来缓存Promise对象的数组 { key: url+param, value: promise }
let promiseList = []
// 检查是否有相同的promise
function checkPromise (url,param) {
let key = url+JSON.stringify(param)
let res = promiseList.filter(item => item.key === key)
// 如果有相同的进行中的promise,直接返回
// 如果没有相同的则需要存入当前的Promise并返回
if (res.length>0) {
console.log('存在并发请求')
return res[0].value
} else {
return false
}
}
function getData(){
const myPromise = null;
let cachePromise = checkPromise(url,param)
if(cachePromise==false){
myPromise = fetchData();
promiseList.push({
key: url+JSON.stringify(param),
value: myPromise,
})
}else{
myPromise = cachePromise;
}
return myPromise;
}