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 相关文章推荐
Extjs学习笔记之五 一个小细节renderTo和applyTo的区别
Jan 07 Javascript
Javascript 倒计时源代码.(时.分.秒) 详细注释版
May 09 Javascript
文本框回车提交与禁止提交示例
Sep 27 Javascript
通过js简单实现将一个文本内容转译成加密文本
Oct 22 Javascript
JavaScript数值转换的三种方式总结
Jul 31 Javascript
jquery实现鼠标滑过小图时显示大图的方法
Jan 14 Javascript
JavaScript对象数组排序实例方法浅析
Jun 15 Javascript
iview日期控件,双向绑定日期格式的方法
Mar 15 Javascript
微信小程序自定义toast组件的方法详解【含动画】
May 11 Javascript
使用vue自定义指令开发表单验证插件validate.js
May 23 Javascript
vue props对象validator自定义函数实例
Nov 13 Javascript
jQuery开发仿QQ版音乐播放器
Jul 10 jQuery
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
fleaphp常用方法分页之Pager使用方法
2011/04/23 PHP
PHP中对用户身份认证实现两种方法
2011/06/04 PHP
PHP编码转换函数 自动转换字符集支持数组转换
2012/12/16 PHP
PHP代码保护--Zend Guard的使用详解
2013/06/03 PHP
在yii中新增一个用户验证的方法详解
2013/06/20 PHP
使用php判断网页是否gzip压缩
2013/06/25 PHP
PHP 7安装使用体验之性能大提升,兼容性强,扩展支持不够(升级PHP要谨慎)
2017/07/27 PHP
一个简单的弹性返回顶部JS代码实现介绍
2013/06/09 Javascript
node.js中的buffer.write方法使用说明
2014/12/10 Javascript
谈谈encodeURI和encodeURIComponent以及escape的区别与应用
2015/11/24 Javascript
很棒的Bootstrap选项卡切换效果
2016/07/01 Javascript
基于jQuery代码实现圆形菜单展开收缩效果
2017/02/13 Javascript
ES6新特性二:Iterator(遍历器)和for-of循环详解
2017/04/20 Javascript
JavaScript实现带有子菜单和控件的slider轮播图效果
2017/11/01 Javascript
cordova入门基础教程及使用中遇到的一些问题总结
2017/11/14 Javascript
vue中子组件调用兄弟组件方法
2018/07/06 Javascript
Vue中使用clipboard实现复制功能
2018/09/05 Javascript
JS对日期操作封装代码实例
2019/11/08 Javascript
vue实现下载文件流完整前后端代码
2020/11/17 Vue.js
[55:26]DOTA2-DPC中国联赛 正赛 Aster vs LBZS BO3 第一场 2月23日
2021/03/11 DOTA
用Python实现一个简单的能够上传下载的HTTP服务器
2015/05/05 Python
简单的Apache+FastCGI+Django配置指南
2015/07/22 Python
示例详解Python3 or Python2 两者之间的差异
2018/08/23 Python
pymongo中group by的操作方法教程
2019/03/22 Python
Python TKinter如何自动关闭主窗口
2020/02/26 Python
python将dict中的unicode打印成中文实例
2020/05/11 Python
python3.8.1+selenium实现登录滑块验证功能
2020/05/22 Python
python自动生成证件号的方法示例
2021/01/14 Python
英国领先的亚洲旅游专家:Wendy Wu Tours
2018/01/21 全球购物
LEGO玩具英国官方商店:LEGO Shop GB
2018/03/27 全球购物
PUMA澳大利亚官方网站:德国运动品牌
2018/10/19 全球购物
编程用JAVA解析XML的方式
2013/07/07 面试题
企业精细化管理实施方案
2014/03/23 职场文书
优秀员工演讲稿
2014/05/19 职场文书
推广普通话主题班会
2015/08/17 职场文书
java如何实现获取客户端ip地址的示例代码
2022/04/07 Java/Android