Javascript AMD学习
我们知道在其它编程语言中, 都有包(命令空间)的概念, 帮助我们更好的管理代码结构. 如java中的package, python中的module. 但是在js语言中, 在一个页面执行环境内, 所有引入的外部的js文件都会在同一个global上下文中执行, 做不到几点: 不能动态加载我们只需要的模块; 没有package的概念, 代码管理混乱. 虽然语言这一层次做不到, 但是从上面一层可以做到, 所以就有了AMD规范标准: Asynchronous module definition.
假设我们现在的文件目录如下:

我们在amd.html里定义两个核心函数: require和define
var modules = {};
var defQ = [];
function onLoad(script, module){
script.addEventListener("load", function(){
var defFactory = defQ.shift();
module.def = defFactory;
module.executed = 1;
}, false);
}
function require(deps, callback){
for(var i = 0; i < deps.length; i++){
var module = {
executed: 0,
url: deps[i]
};
var script = document.createElement("script");
script.type = "text/javascript";
script.src = deps[i];
script.charset = "utf-8";
onLoad(script, module);
modules[deps[i]] = module;
document.body.appendChild(script);
}
var id = setInterval(function(){
var args = [];
for(var i = 0; i < deps.length; i++){
var dep = modules[deps[i]];
if(!dep.executed){
return;
}else{
args.push(dep.def());
}
}
clearInterval(id);
callback.apply(null, args);
}, 1000);
};
function define(factory){
defQ.push(factory);
}
现在我们定义了两个js模块文件: my/a.js和my/b.js, 分别如下:
// my/a.js
define(function(){
return {
name: "tony"
}
});
// my/b.js
define(function(){
return {
name: "lily"
}
});
现在我们可以在其它任何一个地方来动态加载这两个模块文件了, 使用如下:
require(['js/my/a.js', 'js/my/b.js'], function(a, b){
console.debug(a.name + " " + b.name);
});
上面的require和define只是一个简单的AMD思路, 实际中复杂得多, 如要处理循环信赖等等复杂的情况.
浙公网安备 33010602011771号