根据配置文件加载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 相关文章推荐
SeaJS入门教程系列之使用SeaJS(二)
Mar 03 Javascript
jquery禁用右键示例
Apr 28 Javascript
js小数运算出现多位小数如何解决
Oct 08 Javascript
js实现用户输入的小写字母自动转大写字母的方法
Jan 21 Javascript
hammer.js实现图片手势放大效果
Aug 29 Javascript
JS实现的ajax和同源策略(实例讲解)
Dec 01 Javascript
Vue组件化开发思考
Feb 02 Javascript
jQuery实现每隔一段时间自动更换样式的方法分析
May 03 jQuery
React之PureComponent的使用作用
Jul 10 Javascript
如何阻止小程序遮罩层下方图层滚动
Sep 05 Javascript
layui-tree实现Ajax异步请求后动态添加节点的方法
Sep 23 Javascript
Element Badge标记的使用方法
Jul 27 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文本操作类
2006/11/25 PHP
PHP判断远程url是否有效的几种方法小结
2011/10/08 PHP
thinkphp框架下404页面设置 仅三步
2016/05/14 PHP
ThinkPHP Where 条件中常用表达式示例(详解)
2017/03/31 PHP
PHP后期静态绑定实例浅析
2018/12/21 PHP
Firefox outerHTML实现代码
2009/06/04 Javascript
Jquery实现仿新浪微博获取文本框能输入的字数代码
2013/02/22 Javascript
使用Javascript实现选择下拉菜单互移并排序
2016/02/23 Javascript
js实现日历的简单算法
2017/01/24 Javascript
Vue.js实现移动端短信验证码功能
2017/03/29 Javascript
微信小程序使用Socket的实例
2017/09/19 Javascript
解决angularjs前后端分离调用接口传递中文时中文乱码的问题
2018/08/13 Javascript
js使用文件流下载csv文件的实现方法
2019/07/15 Javascript
JQuery实现ul中添加LI和删除指定的Li元素功能完整示例
2019/10/16 jQuery
使用原生JS实现火锅点餐小程序(面向对象思想)
2019/12/10 Javascript
vue项目里面引用svg文件并给svg里面的元素赋值
2020/08/17 Javascript
[29:10]Ti4 冒泡赛第二天 NEWBEE vs Titan 3
2014/07/15 DOTA
python基础教程项目二之画幅好画
2018/04/02 Python
pandas的唯一值、值计数以及成员资格的示例
2018/07/25 Python
Python3之外部文件调用Django程序操作model等文件实现方式
2020/04/07 Python
快速解决pymongo操作mongodb的时区问题
2020/12/05 Python
韩国知名的家庭购物网站:CJmall
2016/08/01 全球购物
巴西电子产品购物网站:Saldão da Informática
2018/01/09 全球购物
Chupi官网:在爱尔兰手工制作的订婚、结婚戒指和精美珠宝
2020/09/28 全球购物
opencv实现图像平移效果
2021/03/24 Python
清洁工岗位职责
2014/01/29 职场文书
跟单业务员岗位职责
2014/03/08 职场文书
环保建议书400字
2014/05/14 职场文书
助人为乐模范事迹材料
2014/06/02 职场文书
群众路线领导对照材料
2014/08/23 职场文书
荆州古城导游词
2015/02/06 职场文书
2016年心理学教育培训学习心得体会
2016/01/12 职场文书
2019毕业论文致谢词
2019/06/24 职场文书
实习报告范文之电话客服岗位
2019/07/26 职场文书
React中的Context应用场景分析
2021/06/11 Javascript
CSS SandBox应用场景及常见问题
2022/06/25 HTML / CSS