资讯专栏INFORMATION COLUMN

【面试系列】之一:关于Cmd和Amd

lordharrd / 1163人阅读

摘要:开篇我叫王彬,现在是百度首页业务部原网页搜团队索部前端的实习,两天前我得知我所在的部门只有两个,而且要分给策略,这就意味着我要面临千军万马过独木桥的秋招。总结我在百度实习时接触到过一个框架,用于百度首页和首页的模块化开发。

之一:关于Cmd和Amd

为什么想起来做这样一个专题呢,答案应该是为了勉励面试笔试秋招中的自己吧!
而且也是为了和我一样的你。

1.开篇

我叫王彬,现在是百度首页业务部(原网页搜团队索部FE前端)的实习FE,
两天前我得知我所在的部门只有两个hc,而且要分给策略rd,
这就意味着我要面临千军万马过独木桥的“秋招”
可能我的描述有点夸张,但是此时此刻的真的是这么感觉的。
我觉得以我现在的水平,可能不会有一家大公司要我,所以我发自内心的厌恶秋招!
但是必须面对!
一起努力吧,希望自己可以一直写下去。
所写的文章肯定有不完善的地方,希望看的朋友可以指正,我会虚心接受一切声音。
好,言归正传!
我今天要写的是关于Amd和Cmd

首先来看这个http://www.zhihu.com/question...
玉伯知乎上的回答

说到Amd和Cmd,你可能和我一样,最先想到的就是require.js以及sea.js
因为两者分别的是Amd和Cmd的代表
在开始深入了解Amd以及Cmd之前,我和大家一样,只是知道这都是js模块化加载的工具
至于模块化加载的好处自然不必多说,用过的应该都懂
那么我们就从require.js和sea.js蔓延开来讲讲Amd和Cmd

2.Amd的代表require.js

Amd是指Asynchronous Module Definition,异步的模块加载机制。是在推广require.js时对模块规范化产出。

以下的内容引自阮一峰老师的博客http://www.ruanyifeng.com/blo...

要说Amd就要先从Common.js说起。

2009年,美国程序员Ryan Dahl创造了node.js项目,将javascript语言用于服务器端编程。
node.js的模块系统,就是参照CommonJS规范实现的。在CommonJS中,有一个全局性方法require(),用于加载模块。假定有一个数学模块math.js,就可以像下面这样加载。

var math = require("math");
math.add(2,3); // 5

有了服务器端模块以后,很自然地,大家就想要客户端模块。而且最好两者能够兼容,一个模块不用修改,在服务器和浏览器都可以运行。
但是,由于一个重大的局限,使得CommonJS规范不适用于浏览器环境。还是上一节的代码,如果在浏览器中运行,会有一个很大的问题,你能看出来吗?

第二行math.add(2,3),在第一行require("math")之后运行,因此必须等math.js加载完成。也就是说,如果加载时间很长,整个应用就会停在那里等。

这对服务器端不是一个问题,因为所有的模块都存放在本地硬盘,可以同步加载完成,等待时间就是硬盘的读取时间。

但是,对于浏览器,这却是一个大问题,因为模块都放在服务器端,等待时间取决于网速的快慢,可能要等很长时间,浏览器处于"假死"状态。

因此,浏览器端的模块,不能采用"同步加载"(synchronous),只能采用"异步加载"(asynchronous)。这就是AMD规范诞生的背景。

下面具体的用法,看一下下面的举例(具体详细配置以及使用方法请大家查看require.js官方文档):

//通过数组引入依赖 ,回调函数通过形参传入依赖 
define(["someModule1", ‘someModule2’], function (someModule1, someModule2) { 

    function foo () { 
        // something 
        someModule1.test(); 
    } 

    return {foo: foo} 
}); 

AMD规范允许输出模块兼容CommonJS规范,这时define方法如下:

define(function (require, exports, module) { 
     
    var reqModule = require("./someModule"); 
    requModule.test(); 
     
    exports.asplode = function () { 
        //something
    } 
}); 

但是值得注意的是:
仍然按照这种写法,加载的模块仍会被提前读取且加载(记住是读取且加载,后面有用),
与下面的这种写法效果一样!

define(["./someModule"], function (require, exports, module, reqModule) { 

    requModule.test(); 
     
    exports.asplode = function () { 
        // something
    } 
}); 

因此我们可以得出结论:
1.Amd推崇的是依赖前置
2.Amd对加载的模块是提前读取并加载

3. Cmd代表的sea.js

Cmd是指Common Module Definition,异步的模块加载机制。是在推广sea.js时对模块规范化产出。
说到Cmd,大家千万不要望文生义,认为这和Common.js在服务器端的加载方式相同,其实并不一样。
其实Cmd更像是Amd和Common.js的升级版,结合了两者的优点。

Common.js可以做到当需要这个模块时,再读取并加载。
Amd可以做到避免Common.js的 “临时读取并加载文件”,它是提前读取并加载。

而Cmd可以做到的是,“提前读取文件,但在需要再加载”,这样可以避免浏览器临时加载文件的假死,也可以避免提前加载引起的逻辑问题。

具体的逻辑问题指什么呢?我们来看这篇图文并茂的讲解:

请戳:https://www.douban.com/note/2...

请仔细看,如果有点懵的话,像我一样,再看两遍。

所以大家叫sea.js懒加载,也就是 “as lazy as possible”,如果你面试的时候说出这句话,面试官一定对你刮目相看。这也是Cmd的标志!
懒加载可以很好的作为判别Amd和Cmd的方法哈!

因此我们可以总结出:
1.Cmd推崇的是就近依赖
2.Cmd对加载的模块是提前读取并不加载,而是在需要时加载

4. 总结

我在百度实习时接触到过一个框架,用于百度PC首页和PAD首页的模块化开发。
这个框架是F框架(移动端由于性能优化的要求使用的是B框架,esl.js),感兴趣的朋友可以深入了解一下。

F框架有一个特点,

F.module("hello", function () {
    // require("world");
    // do something...
}) 

如果代码这么写,虽然require("world")被注释掉了
但是world这个模块依然会被加载,大家知道为什么吗?

答案是:因为F框架遵循的是Amd规范,会正则匹配factory也就是模块的主体函数中的require字段,一但匹配到就会进行前置读取并加载。
所以会出现这种现象。

这个例子希望可以帮助大家理解。
最后再看遍文章开头提到的玉伯大神的问答 http://www.zhihu.com/question... 加深理解

文章的内容并不是全部原创,
我在网上借鉴了许多老师的经验

http://www.zhihu.com/question...
https://www.douban.com/note/2...
http://zccst.iteye.com/blog/2...
http://www.ruanyifeng.com/blo...

感谢以上所有老师的智慧结晶!

下一次想和大家聊聊js原型那些事,争取马上更新!
对啦,大家有没有什么复习数据结构与算法的好办法,希望数据结构与算法大神指点明津!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/87851.html

相关文章

  • [面试专题]JS中模块AMD,CMD,import

    摘要:服务端使用模块规范。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。注意是数组格式工厂方法,返回一个模块函数如果一个模块不依赖其他模块,那么可以直接定义在函数之中。 js中的require、import和export require时代 Javascript社区做了很多努力,在现有的运行环境中,实现模块的效果。 对象写法 把模块写成一个对象,所...

    dreamans 评论0 收藏0
  • [面试专题]JS中模块AMD,CMD,import

    摘要:服务端使用模块规范。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。注意是数组格式工厂方法,返回一个模块函数如果一个模块不依赖其他模块,那么可以直接定义在函数之中。 js中的require、import和export require时代 Javascript社区做了很多努力,在现有的运行环境中,实现模块的效果。 对象写法 把模块写成一个对象,所...

    xinhaip 评论0 收藏0
  • 你不知道的h5

    摘要:目前,常用的模块规范主要有两种和。拦截全局请求一直接引入脚本拦截需要的回调或函数。深刻知道一个良好的命名规范的重要性,同时在项目中也会遇到一些命名的瓶颈。 基于 Three.js 的超快的 3D 开发框架:Whitestorm.js Whitestorm.js 是一款基于 Three.js 超快的 Web 应用 3D 开发框架。它为普通的 Three.js 任务提供封装、使搭建环境、...

    IntMain 评论0 收藏0
  • 前端资源系列(4)-前端学习资源分享&前端面试资源汇总

    摘要:特意对前端学习资源做一个汇总,方便自己学习查阅参考,和好友们共同进步。 特意对前端学习资源做一个汇总,方便自己学习查阅参考,和好友们共同进步。 本以为自己收藏的站点多,可以很快搞定,没想到一入汇总深似海。还有很多不足&遗漏的地方,欢迎补充。有错误的地方,还请斧正... 托管: welcome to git,欢迎交流,感谢star 有好友反应和斧正,会及时更新,平时业务工作时也会不定期更...

    princekin 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<