详解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错误提示的关闭方法详解
Jun 23 PHP
基于PHP创建Cookie数组的详解
Jul 03 PHP
php根据身份证号码计算年龄的实例代码
Jan 18 PHP
php实现mysql数据库操作类分享
Feb 14 PHP
PHP APC配置文件2套和参数详解
Jun 11 PHP
php数组冒泡排序算法实例
May 06 PHP
PHP面向对象程序设计方法实例详解
Dec 24 PHP
php中时间函数date及常用的时间计算
May 12 PHP
PHP实现的登录页面信息提示功能示例
Jul 24 PHP
PHP获取数组中指定的一列实例
Dec 27 PHP
YII框架实现自定义第三方扩展操作示例
Apr 26 PHP
PHP 面向对象程序设计之类属性与类常量实现方法分析
Apr 13 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
PHP概述.
2006/10/09 PHP
PHP、Python和Javascript的装饰器模式对比
2015/02/03 PHP
CodeIgniter针对lighttpd服务器URL重写的方法
2015/06/10 PHP
php中array_column函数简单实现方法
2016/07/11 PHP
php解决DOM乱码的方法示例代码
2016/11/20 PHP
ThinkPHP框架整合微信支付之Native 扫码支付模式二图文详解
2019/04/09 PHP
PHP强制转化的形式整理
2020/05/22 PHP
javascript中的注释使用与注意事项小结
2011/09/20 Javascript
ASP.NET jQuery 实例9  通过控件hyperlink实现返回顶部效果
2012/02/03 Javascript
jQuery实现级联菜单效果(仿淘宝首页菜单动画)
2014/04/10 Javascript
JavaScript中的Math 使用介绍
2014/04/21 Javascript
深入理解JavaScript系列(37):设计模式之享元模式详解
2015/03/04 Javascript
详细分析JavaScript函数定义
2015/07/16 Javascript
jquery实现点击展开列表同时隐藏其他列表
2015/08/10 Javascript
javascript常用的方法整理
2015/08/20 Javascript
有关文件上传 非ajax提交 得到后台数据问题
2016/10/12 Javascript
深入理解ES6学习笔记之块级作用域绑定
2017/08/19 Javascript
vue双花括号的使用方法 附练习题
2017/11/07 Javascript
CentOS7中源码编译安装NodeJS的完整步骤
2018/10/13 NodeJs
vue使用el-upload上传文件及Feign服务间传递文件的方法
2019/03/15 Javascript
vue 实现input表单元素的disabled示例
2019/10/28 Javascript
python基于mysql实现的简单队列以及跨进程锁实例详解
2014/07/07 Python
Python 脚本实现淘宝准点秒杀功能
2019/11/13 Python
Python实现分数序列求和
2020/02/25 Python
python库skimage给灰度图像染色的方法示例
2020/04/27 Python
Python headers请求头如何实现快速添加
2020/11/03 Python
python爬虫请求头的使用
2020/12/01 Python
教师年度考核自我鉴定
2014/01/19 职场文书
大学校运会广播稿
2014/02/03 职场文书
《灰椋鸟》教学反思
2014/04/27 职场文书
预防煤气中毒方案
2014/06/16 职场文书
社区领导班子四风问题原因分析及整改措施
2014/09/28 职场文书
保管员岗位职责
2015/02/14 职场文书
观看禁毒宣传片后的感想
2015/08/11 职场文书
如何使用flask将模型部署为服务
2021/05/13 Python
html5 录制mp3音频支持采样率和比特率设置
2021/07/15 Javascript