详解js异步文件加载器


Posted in PHP onJanuary 24, 2016

我们经常会遇到这种场景,某些页面依赖第三方的插件,而这些插件比较大,不适合打包到页面的主js里(假设我们使用的是cmd的方式,js会打包成一个文件),那么这个时候我们通常会异步获取这些插件文件,并在下载完成后完成初始化的逻辑。

以图片上传为例,我们可能会用到plupload.js这个插件,那么我们会这么写:

!window.plupload ?
    $.getScript( "/assets/plupload/plupload.full.min.js", function() {
      self._initUploader();
    }) :
    self._initUploader();

但是我们的页面通常由多个独立的模块(组件)构成,如果页面上的A、B两个模块都依赖于plupload.js, 那是不是在两个地方都要把上面的代码写一遍。如果这么干,在plupload.js被下载下来之前,可能会发起两个请求,由于是并行下载,js文件可能会被重复下载,而不是第一次下载下来,第二次取缓存的内容。

下图是页面多个组件依赖vue.js的情况(jquery和vue混用的场景):

详解js异步文件加载器

所以,在实际使用中需要加锁,即当脚本正在加载时,不应该再重复请求脚本,等待加载完成后,依次执行后面的逻辑,有promise这个好工具,实现起来很简单。

// vue加载器
var promiseStack = [];
function loadvue() {
  var promise = $.Deferred();
  if (loadvue.lock) {
    promiseStack.push(promise);
    
  } else {
    loadvue.lock = true;
    window.Vue ? 
       promise.resolve() : // 这里写错了,window.Vue为true的时候lock要置为false,我在后面改过来了
       $.getScript( "/assets/vue/vue.min.js", function() {
        loadvue.lock = false;
        promise.resolve();
        promiseStack.forEach(function(prom) {
          prom.resolve();
        });
      });
    
  }
  return promise;
}
window.loadvue = loadvue;

然后在依赖vue.js地方:

loadvue().then(function() { // do something });

再看看请求:

详解js异步文件加载器

好了,到这里似乎解决问题了,但是假如我的页面上存在多个插件依赖,比如既依赖plupload.js又依赖vue.js,难道我要把上面的代码再写一遍(怎么感觉好像说过这话)?这样不就冗余了么?所以我们需要一个异步加载器的生成器,能够帮助我们生成多个异步加载器。

/**
 * @des: js异步加载器生产器
 * @param {string} name  加载器名称
 * @param {string} global 全局变量
 * @param {string} url  加载地址
 **/

var promiseStack = {};

exports.generate = function(name, global, url) {
  var foo = function() {
    if (!promiseStack[name]) {
      promiseStack[name] = [];
    }
    var promise = $.Deferred();
    if (foo.lock) {
      promiseStack[name].push(promise);
      
    } else {
      foo.lock = true;
      if (window[global]) {
        foo.lock = false;
        promise.resolve();
      } else {
        $.getScript(url, function() {
          foo.lock = false;
          promise.resolve();
          promiseStack[name].forEach(function(prom) {
            prom.resolve();
          });
        });
      }
      
    }
    return promise;
  };
  
  return foo;
};

然后我们可以生成异步加载器并赋给window

// 全局加载器
window.loadvue = loader.generate(
'vue', 
'Vue', 
'/assets/vue/vue.min.js');
window.loadPlupload = loader.generate(
'plupload', 
'plupload', 
'/assets/plupload/plupload.full.min.js');

使用的时候同上,这样就基本解决了我们的问题。

以上就是关于js异步文件加载器的详细内容,希望对大家的学习有所帮助。

PHP 相关文章推荐
用PHP和MySQL保存和输出图片
Oct 09 PHP
phpmyadmin的#1251问题
Nov 25 PHP
很让人受教的 提高php代码质量36计
Sep 05 PHP
使用淘宝IP库获取用户ip地理位置
Oct 27 PHP
php不使用插件导出excel的简单方法
Mar 04 PHP
PHP生成不重复随机数的方法汇总
Nov 19 PHP
php读取flash文件高宽帧数背景颜色的方法
Jan 06 PHP
php编写的抽奖程序中奖概率算法
May 14 PHP
PHP文件下载实例代码浅析
Aug 17 PHP
php常用字符串String函数实例总结【转换,替换,计算,截取,加密】
Dec 07 PHP
php curl批处理实现可控并发异步操作示例
May 09 PHP
PHP读取Excel内的图片(phpspreadsheet和PHPExcel扩展库)
Nov 19 PHP
PHP导出Excel实例讲解
Jan 24 #PHP
PHP验证码生成原理和实现
Jan 24 #PHP
详解PHP对象的串行化与反串行化
Jan 24 #PHP
php上传图片获取路径及给表单字段赋值的方法
Jan 23 #PHP
高质量PHP代码的50个实用技巧必备(下)
Jan 22 #PHP
php使用timthumb生成缩略图的方法
Jan 22 #PHP
php session的锁和并发
Jan 22 #PHP
You might like
Laravel实现定时任务的示例代码
2017/08/10 PHP
jquery DOM操作 基于命令改变页面
2010/05/06 Javascript
JS实现点击图片在当前页面放大并可关闭的漂亮效果
2013/10/18 Javascript
js实现弹窗插件功能实例代码分享
2013/12/12 Javascript
Clipboard.js 无需Flash的JavaScript复制粘贴库
2015/10/02 Javascript
Javascript 计算字符串在localStorage中所占字节数
2015/10/21 Javascript
通过设置CSS中的position属性来固定层的位置
2015/12/14 Javascript
javascript实现input file上传图片预览效果
2015/12/31 Javascript
JS实现动态生成表格并提交表格数据向后端
2020/11/25 Javascript
使用Node.js给图片加水印的方法
2016/11/15 Javascript
基于jquery实现二级联动效果
2017/03/30 jQuery
Swiper自定义分页器使用详解
2017/12/28 Javascript
vue实现点击当前标签高亮效果【推荐】
2018/06/22 Javascript
Three.js实现简单3D房间布局
2018/12/30 Javascript
JS数组方法slice()用法实例分析
2020/01/18 Javascript
js 闭包深入理解与实例分析
2020/03/19 Javascript
js实现简易计算器小功能
2020/11/18 Javascript
[51:26]VP vs VG 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
零基础写python爬虫之打包生成exe文件
2014/11/06 Python
在Python中操作字典之setdefault()方法的使用
2015/05/21 Python
Python使用sftp实现上传和下载功能(实例代码)
2017/03/14 Python
django使用xlwt导出excel文件实例代码
2018/02/06 Python
Python装饰器的执行过程实例分析
2018/06/04 Python
python 定时器,轮询定时器的实例
2019/02/20 Python
python给微信好友定时推送消息的示例
2019/02/20 Python
python腾讯语音合成实现过程解析
2019/08/01 Python
pandas的相关系数与协方差实例
2019/12/27 Python
最新PyCharm 2020.2.3永久激活码(亲测有效)
2020/11/26 Python
HTML5实现无刷新修改URL的方法
2019/11/14 HTML / CSS
创建索引时需要注意的事项
2013/05/13 面试题
外贸英语专业求职信范文
2013/12/25 职场文书
高中生活自我鉴定
2014/01/18 职场文书
公开服务承诺制度
2014/03/26 职场文书
小学四年级学生评语
2014/12/26 职场文书
2016年优秀少先队辅导员事迹材料
2016/02/26 职场文书
导游词之藏龙百瀑景区
2019/12/30 职场文书