异步加载text资源,加载一次、执行一次、链式回调

function getText(time,callback) {
    setTimeout(function () {
        callback(time)
    },time)
}

var callbackMap={};//记录加载完成的回调
var resMap={};//记录url
var loadbackMap={};//记录url 加载完成
var loadedMap={};//记录url 加载完成
var loadedI=-1;//记录url 加载完成位置
var orderI=0;//记录url 当前位置
var orderIMap={};//记录num+url=>orderI

var numMap={};//记录url
var allUrlArr=[];
var itemArr={};

function exec(item) {
    console.log(‘exec‘,item)
    if(item.num===1){

    }

}

function loadAll(arr,callback) {
    var urlArr=[];
    for(var i=0;i<arr.length;i++){
        if(arr[i]){
            urlArr.push(arr[i])
            allUrlArr.push(arr[i])
        }
    }
    //缓存回调

    callbackMap[orderI+urlArr.length]=callback;
    console.log(‘加载资源‘,urlArr)

    for(var i=orderI;i<allUrlArr.length;i++){
        console.log(allUrlArr[i],i)
        loadItem(allUrlArr[i],i,function (item) {
            itemArr[item.orderI]=item;
            if(item.orderI-loadedI===1){
                synchro(item.orderI)
            }
        })
    }
    orderI=orderI+urlArr.length;
    //同步执行
    function synchro(i){
        if(i<allUrlArr.length&&itemArr[i]){
            loadedI=i;
            exec(itemArr[i]);
            delete itemArr[i];
            if(callbackMap[i+1]){
                callbackMap[i+1]();
                delete callbackMap[i+1];
            }
            synchro(i + 1);
        }
    }
}
function loadItem(url,orderI,callback) {
    numMap[url]=numMap[url]||0;
    numMap[url]++;
    if(!resMap[url]){
        loadbackMap[numMap[url]+‘-‘+url]=callback;
        orderIMap[numMap[url]+‘-‘+url]=orderI;
        if(numMap[url]===1){
            getText(url,function (text) {
                resMap[url]=text;
                for(var i=1;i<numMap[url]+1;i++){
                    if(loadbackMap[i+‘-‘+url]){
                        loadbackMap[i+‘-‘+url]({
                            url:url,
                            text:text,
                            orderI:orderIMap[i+‘-‘+url],
                            num:i,
                        });
                        delete loadbackMap[i+‘-‘+url];
                    }
                }
            })
        }
    }else{
        callback({
            url:url,
            orderI:orderI,
            text:resMap[url],
            num:numMap[url]
        });
    }
}

loadAll([200,100],function (resMap) {
    console.log(222222)
})
loadAll([20,10],function (resMap) {
    console.log(2222)
})
loadAll([200,100],function (resMap) {
    console.log(222)
})
loadAll([20,10],function (resMap) {
    console.log(22)
})

完整lCache.js 先开始加载先执行

!(function () {
  function getText(url,callback) {
    var xmlhttp=new XMLHttpRequest();
    if(typeof callback!==‘function‘){
      xmlhttp.open("GET",url,false);
      xmlhttp.send();
      return xmlhttp.responseText;
    }
    xmlhttp.onreadystatechange=function () {
      if (this.readyState===4&&this.status===200){
        callback(this.responseText)
      }
    };
    xmlhttp.open("GET",url,true);
    xmlhttp.send();
  }
  //获取文件key
  function getFileKey(url) {
    return url.replace(/(?!\w+)\.\w+\.(js|css)/,‘.$1‘).replace(/\?.+/,‘‘)
  }

  window.LCache={
    cacheMap:{},//缓存的url
    curMap:{},//当前的url
    getText:getText,
    loadChunk:loadChunk,
    storagePrefix:‘LCache-‘,//前缀
    loadAll:loadAll
  }

  var callbackMap={};//记录加载完成的回调
  var resMap={};//记录url
  var loadbackMap={};//记录url 加载完成
  var loadedI=-1;//记录url 加载完成位置
  var orderI=0;//记录url 当前位置
  var orderIMap={};//记录num+url=>orderI

  var numMap={};//记录url
  var allUrlArr=[];
  var itemArr={};

  function loadAll(arr,callback) {
    var urlArr=[];
    for(var i=0;i<arr.length;i++){
      var url=arr[i];
      if(url){
        var key=LCache.storagePrefix+url;
        var preKey=LCache.cacheMap[getFileKey(key)]
        if(key===preKey){
          resMap[url]=localStorage.getItem(key);
        }
        urlArr.push(arr[i])
        allUrlArr.push(arr[i])
      }
    }
    //缓存回调

    callbackMap[orderI+urlArr.length]=callback;
    console.log(‘加载资源‘,urlArr)

    for(var i=orderI;i<allUrlArr.length;i++){
      console.log(allUrlArr[i],i)
      loadItem(allUrlArr[i],i,function (item) {
        itemArr[item.orderI]=item;
        if(item.orderI-loadedI===1){
          synchro(item.orderI)
        }
      })
    }
    orderI=orderI+urlArr.length;
    //同步执行
    function synchro(i){
      if(i<allUrlArr.length&&itemArr[i]){
        loadedI=i;
        exec(itemArr[i]);
        delete itemArr[i];
        if(callbackMap[i+1]){
          callbackMap[i+1]();
          delete callbackMap[i+1];
        }
        synchro(i + 1);
      }
    }
  }
  function loadItem(url,orderI,callback) {
    numMap[url]=numMap[url]||0;
    numMap[url]++;
    if(!resMap[url]){
      loadbackMap[numMap[url]+‘-‘+url]=callback;
      orderIMap[numMap[url]+‘-‘+url]=orderI;
      if(numMap[url]===1){
        getText(url,function (text) {
          resMap[url]=text;
          for(var i=1;i<numMap[url]+1;i++){
            if(loadbackMap[i+‘-‘+url]){
              loadbackMap[i+‘-‘+url]({
                url:url,
                text:text,
                orderI:orderIMap[i+‘-‘+url],
                num:i,
              });
              delete loadbackMap[i+‘-‘+url];
            }
          }
        })
      }
    }else{
      callback({
        url:url,
        orderI:orderI,
        text:resMap[url],
        num:numMap[url]
      });
    }
  }
//渲染js、css
  var head = typeof document!=‘undefined‘&&document.getElementsByTagName(‘head‘)[0];
  function exec(item) {
    if(item.num===1){
      if(/\.css/.test(item.url)){
        var s = document.createElement("style");
        s.setAttribute(‘data-href‘,item.url)
        s.innerHTML = item.text;
        head.appendChild(s)
      } else if(/\.json/.test(item.url)){
        configComponent(JSON.parse(item.text),item.url)
      }else if(/\.js/.test(item.url)){
        var script = document.createElement(‘script‘);
        script.text = item.text;
        head.appendChild( script );
      }
      var key=LCache.storagePrefix+item.url;
      var preKey=LCache.cacheMap[getFileKey(key)]
      //删除旧版本
      localStorage.removeItem(preKey);
      //添加新版本
      try {
        localStorage.setItem(key,item.text);
      }catch (e) {
        clearCache(key,item.text);
      }
    }

  }

  //LCache.js用到的url
  var UpLCacheLib=localStorage.getItem(‘UpLCacheLib‘)||‘‘;
  LCache.curMap[getFileKey(UpLCacheLib)]=UpLCacheLib;

  //获取缓存的url
  for (var i = 0; i < localStorage.length; i++) {
    var key = localStorage.key(i);
    if(key.indexOf(LCache.storagePrefix)===0){
      if(getFileKey(UpLCacheLib)===getFileKey(key)&&UpLCacheLib!==key){
        localStorage.removeItem(key);
      }else{
        LCache.cacheMap[getFileKey(key)]=key;
      }
    }
  }

  //渲染js、css
  var head = typeof document!=‘undefined‘&&document.getElementsByTagName(‘head‘)[0];
  function exec(item){
    if(item.num===1){
      if(/\.css/.test(item.url)){
        var s = document.createElement("style");
        s.setAttribute(‘data-href‘,item.url)
        s.innerHTML = item.text;
        head.appendChild(s)
      } else if(/\.json/.test(item.url)){
        configComponent(JSON.parse(item.text),item.url)
      }else if(/\.js/.test(item.url)){
        var script = document.createElement(‘script‘);
        script.text = item.text;
        head.appendChild( script );
      }
      var key=LCache.storagePrefix+item.url;
      var preKey=LCache.cacheMap[getFileKey(key)]
      //删除旧版本
      localStorage.removeItem(preKey);
      //添加新版本
      try {
        localStorage.setItem(key,item.text);
      }catch (e) {
        clearCache(key,item.text);
      }
    }
  }
  //清除缓存
  function clearCache(key,text) {
    if(key&&text){
      console.log(‘clearCache‘)
      for(var nkey in LCache.cacheMap){
        if(!LCache.curMap[nkey]){
          localStorage.removeItem(LCache.cacheMap[nkey]);
        }
      }
      try {
        localStorage.setItem(key,text);
      }catch (e) {
        clearCache()
      }
    }else{
      console.log(‘clearAllPreCache‘)
      for(var key in LCache.cacheMap){
        localStorage.removeItem(LCache.cacheMap[key]);
      }

    }
  }

//执行增量包
  function execChunk(s1,chunk){
    var ns=‘‘;
    for(var i=0;i<chunk.length;i++){
      var arr=chunk[i];
      if(arr[0]===0){
        ns=ns+s1.substr(arr[1],arr[2])
      }else if(arr[0]===1){
        ns=ns+arr[1]
      }
    }
    return ns;
  }

  //加载增量包
  function loadChunk(curVersion,name) {
    var chunkVersion=localStorage.getItem(name);
    localStorage.setItem(name,curVersion);
    if(chunkVersion&&chunkVersion!==curVersion){
      try {
        var text=getText(‘chunk/‘+chunkVersion+‘-‘+curVersion+‘.json‘)
        var chunkArr=JSON.parse(text);

        for(var i=0;i<chunkArr.length;i++){
          var obj=chunkArr[i]
          var preKey=LCache.storagePrefix+obj.a;
          var key=LCache.storagePrefix+obj.b;
          var s1=localStorage.getItem(preKey);

          if(s1){
            var s2=execChunk(s1,obj.c);
            LCache.cacheMap[getFileKey(preKey)]=key;
            localStorage.removeItem(preKey);
            localStorage.setItem(key,s2);
          }
        }
      }catch (e) {

      }
    }

  }

  //配置组件包
  function configComponent(assetsJSON,relaUrl) {
    Vue.$component=Vue.$component||{};
    if(/^http/.test(relaUrl)){
      relaUrl=relaUrl.replace(/\/webpack.+$/,‘/‘)
    }else{
      relaUrl=‘‘;

    }
    for(var name in assetsJSON){
      if(name&&typeof assetsJSON[name]===‘object‘){
        Vue.component(name,getComponent(name))
      }
    }
    //注册组件
    function getComponent(name) {
      var loadArr=[]
      if(typeof assetsJSON[name]===‘object‘){
        if(typeof assetsJSON[name].css===‘string‘){
          loadArr.push(/^\w/.test(assetsJSON[name].css)&&relaUrl?relaUrl+assetsJSON[name].css:assetsJSON[name].css)
        }
        if(typeof assetsJSON[name].js===‘string‘){
          loadArr.push(/^\w/.test(assetsJSON[name].js)&&relaUrl?relaUrl+assetsJSON[name].js:assetsJSON[name].js)
        }
      }
      return function (resolve) {
        LCache.loadAll(loadArr,function () {
          if(typeof Vue.$component[name]===‘function‘){
            Vue.$component[name](resolve)
          }else if(typeof Vue.$component[name]===‘object‘){
            resolve(Vue.$component[name])
          }
        })
      }
    }
  }
})()

原文地址:https://www.cnblogs.com/caoke/p/12459971.html

时间: 2024-10-07 07:43:09

异步加载text资源,加载一次、执行一次、链式回调的相关文章

刚入前端整合的一个手机端页面适配+预加载+获取资源加载进度等的一个小模板

刚入前端不久,之前主要学的是pc端的布局,到公司之后负责的主要是移动段页面,刚开始时为了使页面适应移动端不同的屏幕大小采用的是百分比加媒体查询的方式,做完一个项目之后,感觉非常不好,虽然最后也基本使页面做到了适配.所以做完这个项目之后,我就在网上查找各种屏幕适配的方案,最终找到了一个通过js控制使页面整体缩放的方案,还有一个就是通过js实时检测屏幕大改变html根字体大小的rem布局方案.目前我在使用的是缩放的方案.整体代码基本上是整合的是大牛们分享的一些实用代码,如有什么bug欢迎提出,共同进

页面性能优化:preload预加载静态资源

本文主要介绍preload的使用,以及与prefetch的区别.然后会聊聊浏览器的加载优先级. preload 提供了一种声明式的命令,让浏览器提前加载指定资源(加载后并不执行),在需要执行的时候再执行.提供的好处主要是 将加载和执行分离开,可不阻塞渲染和 document 的 onload 事件 提前加载指定资源,不再出现依赖的font字体隔了一段时间才刷出 如何使用 preload 使用 link 标签创建 <!-- 使用 link 标签静态标记需要预加载的资源 --><link r

Webkit资源加载介绍

一.webkit资源分类 webkit中有多种资源,大致分为以下几种: HTML文本 CSS样式文本 - CachedCSSStyleSheet 字体 - CachedFont 图片 - CachedImage 只读资源 - CachedRawResource JavaScript文本 - CachedScript SVG - CachedSVGDocument 视频字幕 - CachedTextTrack XSL样式表 - CachedXSLStyleSheet 类图如下: HTML文本是网页

cocos creator基础-(二十四)cc.Director与资源加载策略

1: 了解creator场景切换; 2: 了解director基本的一些接口; 3: 理解资源加载的策略; cc.Director对象 1:游戏里面控制管理整个游戏全局对象,包括了场景切换等,为cc.Director对象; 2:导演对象全局只有一个cc.director,大写的为类, 小写的cc.director为全局的导演对象; 3: cc.director来获取导演对象实例; 4: 游戏中各种管理对象都可以通过cc.director获取,比如物理引擎管理,Action管理, 碰撞检测管理等;

UE4 异步资源加载

On this page: 概述 FStringAssetReferences 和TAssetPtr 资源注册表和对象库 StreamableManager(动态加载管理器)和异步加载 概述 虚幻引擎4中有几个新系统,使得可以更加轻松地异步加载资源数据,这些系统代替了虚幻引擎3中的免搜索内容包中存在的很多功能.这些新方法既可以在开发数据应用也可以在设备上的烘焙数据上进行应用,所以您不必保留两个根据需要加载数据的代码路径.有两种通用的方法可以供您根据需要来引用及加载数据. FStringAsset

Cocos2d-x 3.0多线程异步资源加载

Cocos2d-x从2.x版本到上周刚刚才发布的Cocos2d-x 3.0 Final版,其引擎驱动核心依旧是一个单线程的"死循环",一旦某一帧遇到了"大活儿",比如Size很大的纹理资源加载或网络IO或大量计算,画面将 不可避免出现卡顿以及响应迟缓的现象.从古老的Win32 GUI编程那时起,Guru们就告诉我们:别阻塞主线程(UI线程),让Worker线程去做那些"大活儿"吧. 手机游戏,即便是休闲类的小游戏,往往也涉及大量纹理资源.音视频资

cocos2dx资源加载机制(同步/异步)

首先cocos2dx里的资源,有png,plist(pvr),exportjson(json)大致这三类,我们也从这3类去研究相应的加载代码. 本次代码分析基于: cocos2dx3.2 1.png png格式的资源,从sprite作为一个切入口来分析,一般Sprite的创建如下 Sprite* Sprite::create(const std::string& filename) 参数filename,是图片资源的路径. 内部调用的initWithFile Sprite *sprite = n

也许是被误解的浏览器资源加载优化

几乎每一个前端程序员都知道应该把script标签放在页面底部.关于这个经典的论述可以追溯到Nicholas的 High Performance Javasript 这本书的第一章Loading and Execution中,他之所以建议这么做是因为: Put all <script> tags at the bottom of the page, just inside of the closing </body> tag. This ensures that the page c

【转】Unity3D AssetBundles 动态加载游戏资源

AssetBundles are files which you can export from Unity to contain assets of your choice. These files use a proprietary compressed format and can be loaded on demand in your application. This allows you to stream content like models, textures, audio c