AMD

AMD, Asynchronous Module Definition,即异步模块加载机制,它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句都定义在一个回调函数中,等到依赖加载完成之后,这个回调函数才会运行。
AMD 的诞生,就是为了解决这两个问题:

实现 JavaScript 文件的异步加载,避免网页失去响应
管理模块之间的依赖性,便于代码的编写和维护
AMD标准中,定义了下面两个API:

1.require([module], callback)
2. define(id, [depends], callback)
// 模块定义
 define(id?: String, dependencies?: String[], factory: Function|Object);

id 是模块的名字,它是可选的参数。
dependencies 指定了所要依赖的模块列表,它是一个数组,也是可选的参数。每个依赖的模块的输出都将作为参数一次传入 factory 中。如果没有指定 dependencies,那么它的默认值是 ["require", "exports", "module"]。
factory 是最后一个参数,它包裹了模块的具体实现,它是一个函数或者对象。如果是函数,那么它的返回值就是模块的输出接口或值,如果是对象,此对象应该为模块的输出值。
这里主要是根据模块的 Url,创建了一个异步的 Script 标签,并将模块 id 名称添加到的标签的 data-requiremodule 上,再将这个 Script 标签添加到了 html 页面中。同时为 Script 标签的 load 事件添加了处理函数,当该模块文件被加载完毕的时候,就会触context.onScriptLoad。
但是,在使用require.js的时候,我们必须要提前加载所有的依赖,然后才可以使用,而不是需要使用时再加载。
优点:
适合在浏览器环境中异步加载模块。可以并行加载多个模块。
缺点:
提高了开发成本,并且不能按需加载,而是必须提前加载所有的依赖。

//myModule1.js
define(function() {
    var m1 = {};
    m1.say = function() {
        console.log('Hi myModule1!');
    }
    return m1;
});

//myModule2.js
define(['myModule3'], function(m3) {
    var m2 = {};
    m2.say = function() {
        m3.say();
        console.log('Hi myModule2!');
    }
    return m2;
});

//myModule3.js
define(function() {
    var m3 = {};
    m3.say = function() {
        console.log('Hi myModule3!');
    }
    return m3;
});

//HTML
console.log("before require");
require(['myModule1','myModule2'], function(m1, m2){         
    m1.say();
    m2.say();
});
console.log("after require");
//before require
//after require
//Hi myModule1!
//Hi myModule3!
//Hi myModule2!

HTML中先执行console.log(“before require”);,打印出第一条。
然后执行require,因为require.js是AMD异步加载,所以执行require后的console.log(“after require”);语句,打印出第二条。
执行require依次加载模块。先加载myModule1。发现myModule1的define里无[depends]参数,不依赖其他模块。因此运行define里的factory方法获得myModule1的实例对象m1。
再加载myModule2。发现myModule2依赖myModule3,因此加载myModule3。myModule3无[depends]参数,不依赖其他模块。因此运行factory获得myModule3的实例对象m3。
加载完myModule3后,运行myModule2的factory获得myModule2的实例对象m2。
myModule2也加载完毕后,require的所有模块均加载完毕,运行回调函数。前面获得的实例对象m1和m2作为参数传给回调函数。
运行m1.say();打印出第三条
运行m2.say();,根据方法定义,先运行m3.say();打印出第四条,再运行console.log(‘Hi myModule2!’);打印出第五条。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 以代码爱好者角度来看AMD与CMD 随着浏览器功能越来越完善,前端已经不仅仅是切图做网站,前端在某些方面已经媲美桌...
    鄙人才疏学浅阅读 5,866评论 2 7
  • 在JavaScript发展初期就是为了实现简单的页面交互逻辑,寥寥数语即可;如今CPU、浏览器性能得到了极大的提升...
    George_Wm阅读 3,060评论 0 2
  • 系列文章导航 模块(二) es6 module typescript module 本文参考Javascript模...
    合肥黑阅读 12,880评论 0 14
  • 为什么要使用模块化? 最主要的目的: 解决命名冲突 依赖管理 其他价值 提高代码可读性 代码解耦,提高复用性 CM...
    JamHsiao_aaa4阅读 2,948评论 0 1
  • 今日小寒,少了往年的雪花风飞的美景,多了这个季节不常见的连雨天。
    谢淋阅读 1,549评论 0 0

友情链接更多精彩内容