class LCache{
constructor(load,exec){
this.load=load;//加载函数
this.exec=exec;//执行函数
this.maxLen=100;//最大缓存数
this.nearTimeMap={};//最近访问时间
this.resMap={};//缓存
this.paramsMap={};//当前参数
this.callbackMap={};//当前回调
this.loadedI=-1;//记录url 加载完成位置
this.curIMap={};//访问的位置
this.isloadMap={};//是否正在加载
this.loadbackMap={};//接口加载完成回调
this.numMap={};//被访问几次
this.lnumMap={};//被加载几次
this.allUrlArr=[];
this.itemArr={};
}
loadAll(arr,callback){
const startI=this.allUrlArr.length;
const urlArr=[];
if(arr&&arr.length>0){
for(let i=0;i<arr.length;i++){
if(arr[i]){
urlArr.push(arr[i])
this.allUrlArr.push(arr[i])
}
}
}
if(urlArr.length===0){
urlArr.push('');
this.allUrlArr.push('');
}
const endI=this.allUrlArr.length;
//缓存回调
this.paramsMap[endI]=urlArr;
this.callbackMap[endI]= (k)=> {
const urlArr=this.paramsMap[k];
callback(urlArr.map( (url)=> {
return this.resMap[url]
}));
delete this.paramsMap[k];
if(k-1===this.loadedI){
//清理缓存
this.clearCache();
}
};
console.log('加载资源',urlArr)
for(let i=startI;i<endI;i++){
this.loadItem(this.allUrlArr[i],i, (item)=> {
this.itemArr[item.curI]=item;
if(item.curI-this.loadedI===1){
let k=item.curI;
while (k<this.allUrlArr.length&&this.itemArr[k]){
this.loadedI=k;
this.exec(this.itemArr[k]);
delete this.itemArr[k];
if(this.callbackMap[k+1]){
this.callbackMap[k+1](k+1);
delete this.callbackMap[k+1];
}
k=k+1;
}
}
})
}
}
loadItem(url,curI,callback){
this.numMap[url]=this.numMap[url]||0;
this.lnumMap[url]=this.lnumMap[url]||0;
this.nearTimeMap[url]=new Date().getTime();
this.numMap[url]++;
if(url&&!this.resMap[url]){
this.loadbackMap[this.numMap[url]+'-'+url]=callback;
this.curIMap[this.numMap[url]+'-'+url]=curI;
if(!this.isloadMap[url]){
this.isloadMap[url]=true;
this.load(url, (text)=> {
delete this.isloadMap[url];
this.lnumMap[url]++;
this.resMap[url]=text;
for(let i=1;i<this.numMap[url]+1;i++){
if(this.loadbackMap[i+'-'+url]){
this.loadbackMap[i+'-'+url]({
url:url,
text:text,
curI:this.curIMap[i+'-'+url],
num:i,
lnum:this.lnumMap[url],
});
delete this.loadbackMap[i+'-'+url];
}
}
})
}
}else{
setTimeout( () =>{
callback({
url:url,
curI:curI,
text:this.resMap[url],
num:this.numMap[url],
lnum:this.lnumMap[url]
});
},0)
}
}
//清理缓存,按照访问时间排序
clearCache(){
console.log('clearCache')
const urls=Object.keys(this.resMap)
if(urls.length>this.maxLen){
urls.sort( (url1,url2)=> {
if(this.nearTimeMap[url1]-this.nearTimeMap[url2]>0){
return 1;
}else{
return -1
}
})
const delArr=urls.slice(0,urls.length-this.maxLen);
for(let i=0;i<delArr.length;i++){
const url=delArr[i];
delete this.resMap[url];
delete this.nearTimeMap[url];
}
}
}
}
function load(time,callback) {
setTimeout(function () {
callback('res'+time)
},time)
}
function exec(item) {
console.log(item)
if(item.num===1){
}
}
const aLCache=new LCache(load,exec)
aLCache.loadAll([200,100],function (resMap) {
console.log('callback 1',resMap)
aLCache.loadAll([],function (resMap) {
console.log('callback 5')
})
})
aLCache.loadAll([20,10],function (resMap) {
console.log('callback 2')
aLCache.loadAll([],function (resMap) {
console.log('callback 6')
})
})
aLCache.loadAll([200,100],function (resMap) {
console.log('callback 3')
})
aLCache.loadAll([20,10],function (resMap) {
console.log('callback 4')
console.log(resMap)
})