根据配置文件加载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 相关文章推荐
神奇的代码 通杀各种网站-可随意修改复制页面内容
Jul 17 Javascript
jQuery 1.4 15个你应该知道的新特性(译)
Jan 24 Javascript
突发奇想的一个jquery插件
Nov 19 Javascript
JavaScript文档碎片操作实例分析
Dec 12 Javascript
javascript之IE版本检测超简单方法
Aug 20 Javascript
Bootstrap如何创建表单
Oct 21 Javascript
javascript实现一个网页加载进度loading
Jan 04 Javascript
JS组件系列之Gojs组件 前端图形化插件之利器
Nov 29 Javascript
浅谈vue项目如何打包扔向服务器
May 08 Javascript
Koa2微信公众号开发之本地开发调试环境搭建
May 16 Javascript
回顾Javascript React基础
Jun 15 Javascript
基于form-data请求格式详解
Oct 29 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生成静态HTML速度快类库
2007/03/18 PHP
php下获取客户端ip地址的函数
2010/03/15 PHP
PHP 文本文章分页代码 按标记或长度(不涉及数据库)
2012/06/07 PHP
基于MySQL到MongoDB简易对照表的详解
2013/06/03 PHP
PHP在不同页面间传递Json数据示例代码
2013/06/08 PHP
Laravel 中使用简单的方法跟踪用户是否在线(推荐)
2019/10/30 PHP
多种方法实现360浏览器下禁止自动填写用户名密码
2014/06/16 Javascript
60个很实用的jQuery代码开发技巧收集
2014/12/15 Javascript
JavaScript使用addEventListener添加事件监听用法实例
2015/06/01 Javascript
浅谈Sticky组件的改进实现
2016/03/22 Javascript
javascript中json对象json数组json字符串互转及取值方法
2017/04/19 Javascript
jquery实现简单实用的轮播器
2017/05/23 jQuery
nodejs基础之buffer缓冲区用法分析
2018/12/26 NodeJs
记录vue项目中遇到的一点小问题
2019/05/14 Javascript
Flask解决跨域的问题示例代码
2018/02/12 Python
Django实现学生管理系统
2019/02/26 Python
一文了解Python并发编程的工程实现方法
2019/05/31 Python
pytorch AvgPool2d函数使用详解
2020/01/03 Python
Python将二维列表list的数据输出(TXT,Excel)
2020/04/23 Python
基于python调用jenkins-cli实现快速发布
2020/08/14 Python
意大利简约的休闲品牌:Aspesi
2018/02/08 全球购物
诗普兰迪官方网站:Splendid
2018/09/18 全球购物
美国浴缸、水槽和水龙头购物网站:Vintage Tub & Bath
2019/11/05 全球购物
alice McCALL官网:澳大利亚时尚品牌
2020/11/16 全球购物
使用索引(Index)有哪些需要考虑的因素
2016/10/19 面试题
简述安装Slackware Linux系统的过程
2012/05/08 面试题
学生会离职感言
2014/02/11 职场文书
学校招生宣传广告词
2014/03/19 职场文书
机械工程及自动化专业求职信
2014/09/03 职场文书
消防隐患整改通知书
2015/04/22 职场文书
论语读书笔记
2015/06/26 职场文书
劳保用品管理制度范本
2015/08/06 职场文书
vue使用节流函数的踩坑实例指南
2021/05/20 Vue.js
Python中Numpy和Matplotlib的基本使用指南
2021/11/02 Python
《艾尔登法环》1.03.3补丁上线 碎星伤害调整
2022/04/06 其他游戏
如何让你的Nginx支持分布式追踪详解
2022/07/07 Servers