Javascript模塊化編程(二):AMD規范
這個系列的 第一部分介紹了 Javascript 模塊的基本寫法,今天介紹如何規范地使用模塊。
(接上文)
七、模塊的規范
先想一想,為什么模塊很重要?
因為有了模塊,我們就可以更方便地使用別人的代碼,想要什么功能,就加載什么模塊。
但是,這樣做有一個前提,那就是大家必須以同樣的方式編寫模塊,否則你有你的寫法,我有我的寫法,豈不是亂了套!考慮到 Javascript 模塊現在還沒有官方規范,這一點就更重要了。
目前,通行的 Javascript 模塊規范共有兩種:CommonJS 和 AMD。我主要介紹 AMD,但是要先從 CommonJS 講起。
八、CommonJS
2009年,美國程序員 Ryan Dahl 創造了 node.js 項目,將 javascript 語言用于服務器端編程。
這標志"Javascript 模塊化編程"正式誕生。因為老實說,在瀏覽器環境下,沒有模塊也不是特別大的問題,畢竟網頁程序的復雜性有限;但是在服務器端,一定要有模塊,與操作系統和其他應用程序互動,否則根本沒法編程。
node.js 的模塊系統,就是參照 CommonJS 規范實現的。在 CommonJS 中,有一個全局性方法 require (),用于加載模塊。假定有一個數學模塊 math.js,就可以像下面這樣加載。
var math = require ('math');
</blockquote>然后,就可以調用模塊提供的方法:
var math = require ('math');
math.add (2,3); // 5
</blockquote>因為這個系列主要針對瀏覽器編程,不涉及 node.js,所以對 CommonJS 就不多做介紹了。我們在這里只要知道,require ()用于加載模塊就行了。
九、瀏覽器環境
有了服務器端模塊以后,很自然地,大家就想要客戶端模塊。而且最好兩者能夠兼容,一個模塊不用修改,在服務器和瀏覽器都可以運行。
但是,由于一個重大的局限,使得 CommonJS 規范不適用于瀏覽器環境。還是上一節的代碼,如果在瀏覽器中運行,會有一個很大的問題,你能看出來嗎?
var math = require ('math');
math.add (2, 3);
</blockquote>第二行 Math.add (2, 3),在第一行 require ('math')之后運行,因此必須等 math.js 加載完成。也就是說,如果加載時間很長,整個應用就會停在那里等。
這對服務器端不是一個問題,因為所有的模塊都存放在本地硬盤,可以同步加載完成,等待時間就是硬盤的讀取時間。但是,對于瀏覽器,這卻是一個大問題,因為模塊都放在服務器端,等待時間取決于網速的快慢,可能要等很長時間,瀏覽器處于"假死"狀態。
因此,瀏覽器端的模塊,不能采用"同步加載"(synchronous),只能采用"異步加載"(asynchronous)。這就是 AMD 規范誕生的背景。
十、AMD
AMD 是"Asynchronous Module Definition"的縮寫,意思就是"異步模塊定義"。它采用異步方式加載模塊,模塊的加載不影響它后面語句的運行。所有依賴這個模塊的語句,都定義在一個回調函數中,等到加載完成之后,這個回調函數才會運行。
AMD 也采用 require ()語句加載模塊,但是不同于 CommonJS,它要求兩個參數:
require ([module], callback);
</blockquote>第一個參數[module],是一個數組,里面的成員就是要加載的模塊;第二個參數 callback,則是加載成功之后的回調函數。如果將前面的代碼改寫成 AMD 形式,就是下面這樣:
require (['math'], function (math) {
math.add (2, 3);
});
</blockquote>math.add ()與 math 模塊加載不是同步的,瀏覽器不會發生假死。所以很顯然,AMD 比較適合瀏覽器環境。
目前,主要有兩個 Javascript 庫實現了 AMD 規范:require.js 和 curl.js。本系列的第三部分,將通過介紹 require.js,進一步講解 AMD 的用法,以及如何將模塊化編程投入實戰。
來自: 阮一峰的網絡日志