javascript动态加载二


Posted in Javascript onAugust 22, 2012

在上一篇javascript动态加载中,提到了使用同步加载策略这一个方式来实现如

Using("jquery"); 
Using("User"); $("#ID").click(function(){ 
var user = new User(); 
user.name = "xx"; 
user.show(); 
});

由于JS是单线程的,所以同步策略带来的坏处不少,比如阻止之后的代码运行、造成浏览器假死等问题。
使用异步策略又难以实现先导包 后使用的效果。只能采用callback的形式来进行,这又不是UsingJS想要实现的,毕竟jQuery的getScript函数就可以实现这一方式。

经过一番思考,到底怎么解决导包而且是异步的方式,最后得出一个解决方案。先来看一下采用这个方案后的编程方式。

<div id="panel"></div> <script type="text/javascript" src="js/using-0.4.js"></script> 
<script type="text/javascript"> 
Using("jq"); 
Using("jq"); 
Using("Http"); 
Using.asyn(function(){ 
$("#panel").click(function(){ 
alert("Using jquery object"); 
}); 
Using.fetch("Http",function(){ 
var http = new Using.Modules.Http(); 
http.set("xxx"); 
http.show(); 
}); 
}); 
</script>

如上代码所示,总体来说与同步策略没有太大的修改,只是导入了两次jquery,这里显然是需要处理成只导包一次,并且里面增加了一个Using.asyn函数,具体这个函数做什么用,之后会分析。
都知道,异步策略,是不影响当前运行的,那么,我导入的包,假如正在加载,而其后的代码也正在运行,两者之间也刚好存在依赖关系,那么就会出现异常,怎么解决这两者之间的关系,目前唯一的解决办法就是回调函数。

按照Using的思想,必须是先导包后使用。异步的解决办法就是在模块使用之前,并不真的去进行文件拉取,而是将需要的JS文件放置到一个对象当中,比如Array,当有真正需求的时候,再逐个进行加载。来看看

Using("jq"); 
Using("jq"); 
Using("Http");

是怎么工作的。上一段代码
var moduleList = []; Using.fn = Using.prototype; 
Using.fn.initialize= function(module){ 
!this.exist(moduleList,module) ? moduleList.push(module) : null; 
}

这段代码是略去上下文,截取的Using的原型中的一个初始化方法,从代码得知,其主要的职责就是将需要加载的模块放置到moduleList中,并且进行判断,假如moduleList中含有当前需要加载的模块,那么,不进行任何操作。

那么,什么时候进行加载呢?这个就用到了之前提到的Using.asyn方法,也就是通知Using,现在需要异步加载文件了,并且,在加载完毕之后调用Using.asyn函数的回调函数。同样上一段代码

Using.asyn = function(callback){ 
Using.fn.script(callback); 
}

从代码只能简要的看出,Using.asyn函数调用了Using.fn.script函数,并且将回调函数传给了它。自然,就需要看看其又是怎么工作的。
Using.fn.script = function(callback){ 
var _this = this, 
complete = 0, 
count = moduleList.length, 
len = 0; 
if(count < 1){ 
return; 
} var loadScript = function(){ 
while(len < count){ 
_this.ajax(Using.Config[moduleList[len]],function(){ 
complete++; 
if(complete >= count){ 
callback(); 
} 
}); 
len++; 
} 
} 
!Using.Config ? _this.ajax("/js/config",function(){ 
loadScript(); 
}) : loadScript(); 
}

首先看Using.Config,就是上一篇提到的模块配置文件,以通知Using通过模块名来加载相应的模块文件。

其次就是通过内部函数loadScript来做模块文件的加载,通过一个计数器complete来判断当前已经加载了几个模块,当所有模块加载完毕,则调用回调函数。

整合以上代码,整个思路就是说,通过Using对象来导包,并记录,通过Using.asyn来通知Using进行异步加载,最后由Using.fn.script来实现异步加载并执行回调函数。

还注意到Using.fetch函数,整个函数主要是为了解决当代码运行到一定程度或者某一个需求才要加载的文件,类似于$.getScript文件,在加载之前会进行判断,判断当前需要的模块是否已经加载过,如果加载过则直接执行回调函数。

这一次UsingJS的改动,主要是为了将同步策略改为异步策略,但是同样遗留有很多问题,比如要进行类似$(document).ready,只在文档加载完毕的时候才执行,本身来说,实现这个一个效果并不难,而是编写代码时,脑子凌乱了,一时没办法解决Using.asyn多次调用时,由于异步而产生的多次加载同一个模块,又或者各种莫名其妙的问题,一时没有了头绪,故,将此问题后延,一步一步的解决之。

还有便是导包的顺序,不能任意顺序,当时也想做成任意导包,通过添加依赖关系,来做到由代码解决加载顺序,但是又想到,这个做法没有什么很大的实际意义,编码人员肯定知道文件之间的依赖关系的,如果编码的人不知道文件的加载顺序,就是使用<script>标签形式,照样会出错,而做成依赖关系不仅增加了Using的体积,更重要的是做了一件重复的事情。不知道这样理解对不对。

Javascript 相关文章推荐
JQuery插件fancybox无法在弹出层使用左右键的解决办法
Dec 25 Javascript
Jquery实现侧边栏跟随滚动条固定(兼容IE6)
Apr 02 Javascript
js实现禁止中文输入的方法
Jan 14 Javascript
图解Sublime Text3使用技巧
Dec 21 Javascript
js实现定时进度条完成后切换图片
Jan 04 Javascript
JavaScript方法_动力节点Java学院整理
Jun 28 Javascript
Vue基于NUXT的SSR详解
Oct 24 Javascript
bootstrap Table的一些小操作
Nov 01 Javascript
详解如何在微信小程序中愉快地使用sass
Jul 30 Javascript
解决angularJS中input标签的ng-change事件无效问题
Sep 13 Javascript
一些可能会用到的Node.js面试题
Jun 15 Javascript
Webpack3+React16代码分割的实现
Mar 03 Javascript
javascript动态加载实现方法一
Aug 22 #Javascript
原生js写的放大镜效果
Aug 22 #Javascript
window.open不被拦截的实现代码
Aug 22 #Javascript
EASYUI TREEGRID异步加载数据实现方法
Aug 22 #Javascript
网页打开自动最大化的js代码
Aug 22 #Javascript
精心挑选的12款优秀的基于jQuery的手风琴效果插件和教程
Aug 22 #Javascript
eval的两组性能测试数据
Aug 17 #Javascript
You might like
php中通过smtp发邮件的类,测试通过
2007/01/22 PHP
php实现html标签闭合检测与修复方法
2015/07/09 PHP
php连接oracle数据库的方法(测试成功)
2016/05/26 PHP
PHP中字符串长度的截取用法示例
2017/01/12 PHP
PHP判断数组是否为空的常用方法(五种方法)
2017/02/08 PHP
php使用json_decode后数字对象转换成了科学计数法的解决方法
2017/02/20 PHP
laravel多条件查询方法(and,or嵌套查询)
2019/10/09 PHP
php设计模式之正面模式实例分析【星际争霸游戏案例】
2020/03/24 PHP
用jquery来定位
2007/02/20 Javascript
JavaScript 模拟用户单击事件
2009/12/31 Javascript
js中eval详解
2012/03/30 Javascript
关于javascript中的typeof和instanceof介绍
2012/12/04 Javascript
浅析JavaScript原型继承的陷阱
2013/12/03 Javascript
angularjs实现与服务器交互分享
2014/06/24 Javascript
JS小游戏之极速快跑源码详解
2014/09/25 Javascript
嵌入式iframe子页面与父页面js通信的方法
2015/01/20 Javascript
配置Grunt的Task时通配符支持和动态生成文件名问题
2015/09/06 Javascript
AngularJS通过$http和服务器通信详解
2016/09/21 Javascript
JS仿淘宝搜索框用户输入事件的实现
2017/06/19 Javascript
使用layer弹窗和layui表单实现新增功能
2018/08/09 Javascript
Element-ui自定义table表头、修改列标题样式、添加tooltip、:render-header使用
2019/04/11 Javascript
[47:46]完美世界DOTA2联赛 Magma vs GXR 第三场 11.07
2020/11/10 DOTA
python运行其他程序的实现方法
2017/07/14 Python
Python简单定义与使用字典dict的方法示例
2017/07/25 Python
python统计指定目录内文件的代码行数
2019/09/19 Python
介绍一下游标
2012/01/10 面试题
大学新生军训个人的自我评价
2013/10/03 职场文书
生产部统计员岗位职责
2014/01/05 职场文书
公务员职业生涯规划书范文  
2014/01/19 职场文书
销售业务员岗位职责
2014/01/29 职场文书
房屋转让协议书范本
2014/04/11 职场文书
毕业生工作求职信
2014/06/30 职场文书
1000字打架检讨书
2014/11/03 职场文书
2014年党务工作总结
2014/11/25 职场文书
教师学期个人总结
2015/02/11 职场文书
优秀班干部主要事迹材料
2015/11/04 职场文书