根据配置文件加载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 相关文章推荐
JQuery实现自定义对话框的代码
Jun 15 Javascript
JQuery下关于$.Ready()的分析
Dec 13 Javascript
window.location.href的用法(动态输出跳转)
Aug 09 Javascript
js实现精美的图片跟随鼠标效果实例
May 16 Javascript
使用基于Node.js的构建工具Grunt来发布ASP.NET MVC项目
Feb 15 Javascript
jQuery实现为LI列表前3行设置样式的方法【2种方法】
Sep 04 Javascript
javascript实现右下角广告框效果
Feb 01 Javascript
Js自动截取字符串长度,添加省略号(……)的实现方法
Mar 06 Javascript
axios学习教程全攻略
Mar 26 Javascript
js图片上传的封装代码
Aug 01 Javascript
微信小程序商品详情页规格属性选择示例代码
Oct 30 Javascript
基于js中的存储键值对以及注意事项介绍
Mar 30 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
《神奇女侠:血脉》神力女超人大战犯罪公司
2020/04/09 欧美动漫
支持oicq头像的留言簿(一)
2006/10/09 PHP
将文件夹压缩成zip文件的php代码
2009/12/14 PHP
php echo()和print()、require()和include()函数区别说明
2010/03/27 PHP
php+ajax 实现输入读取数据库显示匹配信息
2015/10/08 PHP
学习php设计模式 php实现策略模式(strategy)
2015/12/07 PHP
php5.2的curl-bug 服务器被php进程卡死问题排查
2016/09/19 PHP
yii2 resetful 授权验证详解
2017/05/18 PHP
javascript 动态设置已知select的option的value值的代码
2009/12/16 Javascript
js切换光标示例代码
2013/10/10 Javascript
判定是否原生方法的JS代码
2013/11/12 Javascript
js给onclick赋值传参数的两种方法
2013/11/25 Javascript
Javascript浅谈之this
2013/12/17 Javascript
jquery中页面Ajax方法$.load的功能使用介绍
2014/10/20 Javascript
$.extend 的一个小问题
2015/06/18 Javascript
javascript实现3D变换的立体圆圈实例
2015/08/06 Javascript
如何实现json数据可视化详解
2016/11/24 Javascript
微信小程序如何加载数据库真实数据的实现
2020/03/04 Javascript
JS写滑稽笑脸运动效果
2020/05/28 Javascript
python基础教程之实现石头剪刀布游戏示例
2014/02/11 Python
CentOS7.3编译安装Python3.6.2的方法
2018/01/22 Python
Python如何筛选序列中的元素的方法实现
2019/07/15 Python
python实现在函数中修改变量值的方法
2019/07/16 Python
python GUI库图形界面开发之PyQt5动态(可拖动控件大小)布局控件QSplitter详细使用方法与实例
2020/03/06 Python
Pycharm如何导入python文件及解决报错问题
2020/05/10 Python
基于python实现模拟数据结构模型
2020/06/12 Python
python爬虫中的url下载器用法详解
2020/11/30 Python
欧铁通票官方在线销售网站:Eurail.com
2017/10/14 全球购物
客服服务心得体会
2013/12/30 职场文书
学生思想表现的评语
2014/01/30 职场文书
幼儿园教学管理制度
2014/02/04 职场文书
鲜花方阵解说词
2014/02/13 职场文书
升职演讲稿范文
2014/05/23 职场文书
质量保证书怎么写
2015/02/27 职场文书
quickjs 封装 JavaScript 沙箱详情
2021/11/02 Javascript
Nginx如何限制IP访问只允许特定域名访问
2022/07/23 Servers