根据配置文件加载js依赖模块


Posted in Javascript onDecember 29, 2014

要求:

根据下面的配置文件

module=[

{'name':'jquery','src':'/js/lib/jquery-1.8.3.js'},

{'name':'swfobject','src':'/js/utils/swfobject.js'},

{'name':'fancybox','src':'/js/jquery/jquery.fancybox.js','require':['jquery']},

{'name':'uploadify','src':'/js/utils/uploadify.js','require':['swfobject']},

{'name':'jqform','src':'/js/jquery/jquery.form.js','require':['jquery']},

{'name':'register','src':'/js/page/reg.js','require':['jqform']},

{'name':'login','src':'/js/page/login.js','require':['fancybox','jqform']},

{'name':'upload','src':'/js/page/upload.js','require':['fancybox','jqform','uploadify']}

]

写一个函数

def getfiles(name)

返回 加载某个name指定的页面,要加载的js文件列表,有依赖的要先加载

小菜解法

    此题粗看起来很简单,实则不然。

     难点在于依赖模块的加载时机。假如有这样的依赖关系:A-B&C、B-C,A模块依赖B模块和C模块,同时B模块又依赖了C模块,总不能让C加载两次吧!

     小菜给出的这个解法,只是一个思路,肯定有比这更好的算法,小菜觉得可以用二叉树之类的算法解决,但小菜不会呀~~~

     此算法没有考虑循环依赖的情景。

     代码如下:

 /**

  * 不考虑循环依赖

  * @type {Function}

  */

 var loadModule = (function(){

     /**

      * 业务逻辑封装

      * @type {{chainHead: {}, chainCurrent: {}, srcCache: {}, main: main, load: load, findModule: findModule}}

      */

     var logics = {

         chainHead: {},     //链表头

         chainCurrent: {},  //链表当前节点

         srcCache: {},      //module src 缓存

         /**

          * 对外接口

          * @param modules  配置对象

          * @param name  模块名称

          * @returns {Array} 依赖模块列表,按照加载先后顺序排列

          */

         main: function(modules, name){

             var nameArray = [],  //模块名称列表

                 srcArray = [],   //依赖模块列表

                 nameStr = "",    //模块名称字符串集

                 repeatRegex = /(^| )([\w]+ ).*\2/,  //模块名称去重正则

                 i = 0;

             //粗略加载所有依赖模块

             this.load(modules, name)

             //构造模块名称字符串集

             this.chainCurrent = this.chainHead;

             while(this.chainCurrent.next){

                 nameArray.push(this.chainCurrent.name);

                 this.chainCurrent = this.chainCurrent.next;

             }

             nameStr = nameArray.join(" ") + " ";  //统一标准,末尾补一个空格

             //依赖模块去重

             while(repeatRegex.exec(nameStr)){

                 nameStr = nameStr.replace(repeatRegex, function(g0, g1, g2){

                     return g0.substring(0, (g0.length - g2.length));

                 });

             }

             nameStr = nameStr.substring(0, (nameStr.length - 1));  //去掉补充的多余空格

             //依赖模块名称转换为模块路径

             nameArray = nameStr.split(" ");

             for(i = 0; i < nameArray.length; i++){

                 srcArray.push(this.srcCache[nameArray[i]]);

             }

             return srcArray;

         },

         /**

          * 递归加载模块

          * @param modules  配置对象

          * @param name  模块名称

          */

         load: function(modules, name){

             var node = {},

                 module = this.findModule.call(modules, "name", name),

                 i = 0;

             //判断模块是否存在

             if(!module){

                 throw Error("依赖模块 " + name +" 未找到");

             }

             //构造模块依赖链表

             node.name = name;

 //            node.src = module.src;

             this.srcCache[name] = module.src;

             node.next = this.chainHead;

             this.chainHead = node;

             //递归依赖

             if(module.require && module.require.length){

                 for(i = 0;i < module.require.length; i++){

                     this.load(modules, module.require[i]);

                 }

             }

         },

         /**

          * 根据指定属性名称和属性值查找模块

          * @param name  属性名称

          * @param value  属性值

          * @returns {*}

          */

         findModule: function(name, value){

             var array = this,

                 item = {},

                 i = 0;

             //遍历模块

             for(i = 0; i < array.length; i++){

                 item = array[i];

                 //获取指定模块

                 if(item && item[name] === value){

                     return item;

                 }

             }

             //找不到返回null

             return null;

         }

     };

     //暴露对外接口

     return function(){

         return logics.main.apply(logics, arguments);

     };

 }());

 /**

  * Test Usecase

  * @type {*[]}

  */

 var modules=[

     {'name':'jquery','src':'/js/lib/jquery-1.8.3.js'},

     {'name':'swfobject','src':'/js/utils/swfobject.js'},

     {'name':'fancybox','src':'/js/jquery/jquery.fancybox.js','require':['jquery']},

     {'name':'uploadify','src':'/js/utils/uploadify.js','require':['swfobject']},

     {'name':'jqform','src':'/js/jquery/jquery.form.js','require':['jquery']},

     {'name':'register','src':'/js/page/reg.js','require':['jqform']},

     {'name':'login','src':'/js/page/login.js','require':['fancybox','jqform']},

     {'name':'upload','src':'/js/page/upload.js','require':['fancybox','jqform','login','uploadify']}

 ];

 console.log(loadModule(modules, "upload"));
Javascript 相关文章推荐
仿163填写邮件地址自动显示下拉(无优化)
Nov 05 Javascript
document.compatMode介绍
May 21 Javascript
jQuery动态添加
Apr 07 Javascript
JS创建事件的三种方法(实例代码)
May 12 Javascript
JS实现获取剪贴板内容的方法
Jun 21 Javascript
微信小程序 教程之注册页面
Oct 17 Javascript
js 输入框 正则表达式(菜鸟必看教程)
Feb 19 Javascript
vue计算属性时v-for处理数组时遇到的一个bug问题
Jan 21 Javascript
vue2.0+ 从插件开发到npm发布的示例代码
Apr 28 Javascript
JS实现判断图片是否加载完成的方法分析
Jul 31 Javascript
vuedraggable+element ui实现页面控件拖拽排序效果
Jul 29 Javascript
Javascript数组方法reduce的妙用之处分享
Jun 10 Javascript
JavaScript中的console.dir()函数介绍
Dec 29 #Javascript
JavaScript中的console.group()函数详细介绍
Dec 29 #Javascript
小米公司JavaScript面试题
Dec 29 #Javascript
谷歌浏览器调试JavaScript小技巧
Dec 29 #Javascript
JavaScript中的console.trace()函数介绍
Dec 29 #Javascript
JavaScript中的console.profile()函数详细介绍
Dec 29 #Javascript
jQuery中element选择器用法实例
Dec 29 #Javascript
You might like
PHP 图片文件上传实现代码
2010/12/29 PHP
php在多维数组中根据键名快速查询其父键以及父键值的代码
2011/05/07 PHP
prototype.js的Ajax对象
2006/09/23 Javascript
jquery 必填项判断表单是否为空的方法
2008/09/14 Javascript
ExtJS 2.0实用简明教程 之Border区域布局
2009/04/29 Javascript
js 遍历对象的属性的代码
2011/12/29 Javascript
Raphael带文本标签可拖动的图形实现代码
2013/02/20 Javascript
基于MVC3方式实现下拉列表联动(JQuery)
2013/09/02 Javascript
jQuery获得页面元素的绝对/相对位置即绝对X,Y坐标
2014/03/06 Javascript
HTML+CSS+JS实现完美兼容各大浏览器的TABLE固定列
2015/04/26 Javascript
Javascript 高阶函数使用介绍
2015/06/15 Javascript
深入理解JavaScript编程中的原型概念
2015/06/25 Javascript
jQuery实现表格文本框淡入更改值后淡出效果
2016/09/27 Javascript
bootstrap-datetimepicker实现只显示到日期的方法
2016/11/25 Javascript
Three.js 再探 - 写一个微信跳一跳极简版游戏
2018/01/04 Javascript
js/jQuery实现全选效果
2019/06/17 jQuery
JS 获取文件后缀,判断文件类型(比如是否为图片格式)
2020/05/09 Javascript
[01:20]DOTA2上海特级锦标赛现场采访:谁的ID最受青睐
2016/03/25 DOTA
python通过urllib2爬网页上种子下载示例
2014/02/24 Python
Ubuntu下Anaconda和Pycharm配置方法详解
2019/06/14 Python
python实现切割url得到域名、协议、主机名等各个字段的例子
2019/07/25 Python
关于TensorFlow新旧版本函数接口变化详解
2020/02/10 Python
Python动态导入模块:__import__、importlib、动态导入的使用场景实例分析
2020/03/30 Python
浅谈tensorflow中dataset.shuffle和dataset.batch dataset.repeat注意点
2020/06/08 Python
HTML5实现可缩放时钟代码
2017/08/28 HTML / CSS
欧姆龙医疗欧洲有限公司:Omron Healthcare Europe B.V
2020/06/13 全球购物
市场营销专业个人求职信范文
2013/12/14 职场文书
观看《永远的雷锋》心得体会
2014/03/12 职场文书
考核工作实施方案
2014/03/30 职场文书
舞蹈专业求职信
2014/06/13 职场文书
金融保险专业求职信
2014/09/03 职场文书
十一国庆节“向国旗敬礼”主题班会活动方案
2014/09/27 职场文书
师德师风整改措施
2014/10/24 职场文书
总经理聘用协议书
2015/09/21 职场文书
《丑小鸭》教学反思
2016/02/19 职场文书
Python编解码问题及文本文件处理方法详解
2021/06/20 Python