详解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 相关文章推荐
ip签名探针
Oct 09 PHP
PHP无限分类代码,支持数组格式化、直接输出菜单两种方式
May 18 PHP
php学习笔记之面向对象编程
Dec 29 PHP
PHP下获取上个月、下个月、本月的日期(strtotime,date)
Feb 02 PHP
php对包含html标签的字符串进行截取的函数分享
Jun 19 PHP
php实现的短网址算法分享
Jun 20 PHP
ThinkPHP的URL重写问题
Jun 22 PHP
mod_php、FastCGI、PHP-FPM等PHP运行方式对比
Jul 02 PHP
thinkPHP基于ajax实现的菜单与分页示例
Jul 12 PHP
PHP文件操作详解
Dec 30 PHP
ThinkPHP框架中使用Memcached缓存数据的方法
Mar 31 PHP
PHP配置文件php.ini中打开错误报告的设置方法
Jan 09 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
星际争霸任务指南——人族
2020/03/04 星际争霸
业余方法DIY电子管FM收音机
2021/03/02 无线电
PHP实现即时输出、实时输出内容方法
2015/05/27 PHP
一段好玩的JavaScript代码
2006/12/01 Javascript
基于jQuery图片平滑连续滚动插件
2009/04/27 Javascript
Js 随机数产生6位数字
2010/05/13 Javascript
document.getElementById方法在Firefox与IE中的区别
2010/05/18 Javascript
js对象关系图 方便dom操作
2012/03/18 Javascript
jquery命令汇总,方便使用jquery的朋友
2012/06/26 Javascript
js数组的操作详解
2013/03/27 Javascript
jquery获取复选框checkbox的值的简单实现方法
2016/05/26 Javascript
JavaScript中的各种操作符使用总结
2016/05/26 Javascript
利用jQuery解析获取JSON数据
2017/04/08 jQuery
jQuery实现锚点向下平滑滚动特效示例
2017/08/29 jQuery
详解es6超好用的语法糖Decorator
2018/08/01 Javascript
基于element-ui组件手动实现单选和上传功能
2018/12/06 Javascript
javascript/jquery实现点击触发事件的方法分析
2019/11/11 jQuery
JS异步宏队列微队列原理详解
2020/09/09 Javascript
Javascript执行上下文顺序的深入讲解
2020/11/04 Javascript
vue 中使用print.js导出pdf操作
2020/11/13 Javascript
python编程开发之日期操作实例分析
2015/11/13 Python
详解python发送各类邮件的主要方法
2016/12/22 Python
python3.6.3转化为win-exe文件发布的方法
2018/10/31 Python
使用python的pandas为你的股票绘制趋势图
2019/06/26 Python
ansible动态Inventory主机清单配置遇到的坑
2020/01/19 Python
Pycharm中安装wordcloud等库失败问题及终端通过pip安装的Python库如何添加到Pycharm解释器中(推荐)
2020/05/10 Python
美国益智玩具购物网站:Fat Brain Toys
2017/11/03 全球购物
法律进企业活动方案
2014/03/04 职场文书
党建示范点实施方案
2014/03/12 职场文书
买卖车协议书
2014/04/21 职场文书
国旗下的讲话演讲稿
2014/05/08 职场文书
建筑学专业自荐书
2014/07/09 职场文书
市场营销专业毕业生求职信
2014/07/21 职场文书
2016年暑假学生家长评语
2015/12/01 职场文书
2019年第四季度财务部门工作计划
2019/11/02 职场文书
Pandas-DataFrame知识点汇总
2022/03/16 Python