异步模块定义(AMD)的整体目标是提供模块化的JavaScript解决方案,以便开发人员使用。它诞生于使用XHR+eval的Dojo开发经验,这种格式的支持者希望能避免未来的任何解决方案受到过去解决方案缺点的影响。
AMD模块格式本身就是对定义模块的建议,其模块和依赖都可以进行异步加载。它有很多独特的优点,包括可以异步,并且本质上具有高度灵活性,消除了代码和模块之间可能惯有的紧耦合。
AMD有两个关键概念,他们是用于模块定义的define方法和用于处理模块加载的require方法。define用于定义已命名或未命名模块:
define(module_id,[dependencies],definition function实例化模块或对象的函数)
module_id是一个可选的参数,它通常只在非AMD连接工具被使用时才需要。当遗漏这个 参数时,我们称这个模块为匿名的。
当使用匿名模块时,模块的概念是DRY,以便更容易的避免文件名和代码重复。因为代码更为轻便了,不需要修改代码本身或改变其模块ID,就可以将它很容易的移动到其他的位置。
dependencies参数表示我们定义模块所需的依赖数组。
最后一个参数时用于执行实例化模块的函数。
示例:了解AMD:define()
define(["foo","bar"],function(foo,bar){ // 模块定义函数,依赖(foo和bar)作为参数映射到函数上 var myModule = { doStuff:function(){ console.log("Yay!Stuff"); } }; // 返回定义模块的输出(例如:要暴露的内容) return myModule; }); //另外一种方式 define(["math","graph"],function(math,graph){ return { plot:function(x,y){ return graph.drawPie(math.randomGrid(x,y)); } } });require通常用于加载顶级JavaScript文件或模块的代码。
示例:动态加载依赖
define(function(require){ var isReady = false, foolbar; require(["foo","bar"],function(foo,bar){ isReady = true; foolbar = foo() + bar(); }); return { isReady: isReady, foolbar : foolbar }; });
示例:了解AMD插件
define(["./templates","text!./template.md","css!./template.css"],function(templates, template){ console.log(templates); });
具有延迟依赖的模块代码:
define(["lib/Deferred"],function(Deferred){ var defer = new Deferred(); require(["lib/templates/?index.html"],function(template){ defer.resolve({template:template}); }); return defer.promise(); })