详解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 相关文章推荐
在PHP3中实现SESSION的功能(一)
Oct 09 PHP
查找php配置文件php.ini所在路径的二种方法
May 26 PHP
ThinkPHP3.1查询语言详解
Jun 19 PHP
PHP curl伪造IP地址和header信息代码实例
Apr 27 PHP
PHP 中 Orientation 属性判断上传图片是否需要旋转
Oct 16 PHP
PHP实现linux命令tail -f
Feb 22 PHP
php文件操作小结(删除指定文件/获取文件夹下的文件名/读取文件夹下图片名)
May 09 PHP
PHP获取用户客户端真实IP的解决方案
Oct 10 PHP
轻松实现php文件上传功能
Feb 17 PHP
PHP使用HTML5 FileApi实现Ajax上传文件功能示例
Jul 01 PHP
Yii框架响应组件用法实例分析
Sep 04 PHP
Laravel 微信小程序后端实现用户登录的示例代码
Nov 26 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上传功能集后缀名判断和随机命名(强力推荐)
2015/09/10 PHP
Yii2框架中使用PHPExcel导出Excel文件的示例
2017/08/09 PHP
两个DIV等高的JS的实现代码
2007/12/23 Javascript
javascript CSS画图之基础篇
2009/07/29 Javascript
javascript 函数及作用域总结介绍
2013/11/12 Javascript
通过js来制作复选框的全选和不选效果
2014/05/22 Javascript
两种方法实现在HTML页面加载完毕后运行某个js
2014/06/16 Javascript
php,js,css字符串截取的办法集锦
2014/09/26 Javascript
jQuery实现弹出窗口中切换登录与注册表单
2015/06/05 Javascript
javascript中caller和callee详解
2015/08/10 Javascript
jQuery实现仿QQ空间装扮预览图片的鼠标提示效果代码
2015/10/30 Javascript
基于javascript实现九九乘法表
2016/03/27 Javascript
AngularJS ng-style中使用filter
2016/09/21 Javascript
JS实现的自动打字效果示例
2017/03/10 Javascript
详解vue2.0组件通信各种情况总结与实例分析
2017/03/22 Javascript
Vue2 模板template的四种写法总结
2018/02/23 Javascript
关于TypeScript模块导入的那些事
2018/06/12 Javascript
vue左侧菜单,树形图递归实现代码
2018/08/24 Javascript
Angular2中监听数据更新的方法
2018/08/31 Javascript
VUE脚手架的下载和配置步骤详解
2019/04/01 Javascript
详解小程序设置缓存并且不覆盖原有数据
2019/04/15 Javascript
[02:43]2014DOTA2国际邀请赛 官方Alliance战队纪录片
2014/07/14 DOTA
Python的Bottle框架中返回静态文件和JSON对象的方法
2015/04/30 Python
使用Python的Twisted框架构建非阻塞下载程序的实例教程
2016/05/25 Python
基于python的多进程共享变量正确打开方式
2018/04/28 Python
用TensorFlow实现lasso回归和岭回归算法的示例
2018/05/02 Python
python验证码识别教程之滑动验证码
2018/06/04 Python
Atom的python插件和常用插件说明
2018/07/08 Python
pyqt5 禁止窗口最大化和禁止窗口拉伸的方法
2019/06/18 Python
Python的赋值、深拷贝与浅拷贝的区别详解
2020/02/12 Python
绝对令人的惊叹的CSS3折叠效果(3D效果)整理
2012/12/30 HTML / CSS
Html5新特性用canvas标签画多条直线附效果截图
2014/06/30 HTML / CSS
员工生日活动方案
2014/08/24 职场文书
2014基层党员批评与自我批评范文
2014/09/24 职场文书
2015年置业顾问工作总结
2015/04/07 职场文书
广播稿:校园广播稿范文
2019/04/17 职场文书