2014-08-29 81 views
1

requireJS讓我頭痛atm。 requireJS是AMD,根據定義,它是異步的。通常我會定義一個像這樣的模塊。使用requireJS模塊定義的差異

define("some Name", ["./moduleOne"],function(moduleOne){ 

    //this would be undefined 
    moduleOne.whatEver(); 

    var aMethod = function(){ 
    //user aModule.whatever(); 
    } 

    return { 
    method: aMethod; 
    } 
}); 

好吧,我得到了我不能直接使用moduelOne.whatever,因爲它是異步加載和它的不存在,如果回調被調用。

第一個問題,這是正確的嗎?

現在,如果我的模塊定義改成這樣:

define("some Name", function(require, exports){ 

    var moduleOne = require(".moduleOne");  

    //this is OK 
    moduleOne.whatEver(); 

    var aMethod = function(){ 
    //user aModule.whatever(); 
    } 

    exports.method = aMethod; 
}); 

我可以直接使用aModule.whatever。當我從文檔中讀取時,使用這種(commonJS)風格,需要使用Function.prototype.toString解析函數,看到require語句並直接加載模塊。

我很確定,我在這裏誤解了一些東西,如果第二個樣式是真正同步的,那麼某人可以解釋究竟是如何requireJS的作品會很好。

謝謝

回答

3

你誤會了它的工作原理。

例子,你在你的問題給執行的順序是:

  1. 東西需要一個名爲some_Name模塊。 (我不認爲RequireJS對帶有空格的模塊名稱感到滿意,因此我假設模塊名稱帶有下劃線。)

  2. RequireJS查找模塊some_Name的依賴關係和工廠函數。在定義模塊時,該工廠的功能是define

    a。如果define("some_Name"...在這一步之前被稱爲,那麼RequireJS只會得到define的依賴關係和工廠函數。

    b。如果define("some_Name"...尚未執行,RequireJS將轉到網絡並嘗試獲取包含define調用的文件並執行它。按照慣例,這將是一個與模塊名稱+ .js擴展名同名的文件,但是這可以在RequireJS的配置中重寫。

  3. RequireJS檢查是否加載了依賴關係。如果不是,那麼它會爲每個尚未加載的依賴項發出require調用。

  4. RequireJS用已解決的依賴關係調用工廠函數。

請注意,我沒有在這裏查看所有可能的場景。我堅持最常見的情況來保持簡單。

所以......

好吧,我得到了我不能直接使用moduelOne。不管是因爲它加載了異步,而且如果回調被調用,它不在那裏。

第一個問題,這是正確的嗎?

不,這是不正確的。在執行moduleOne.whatEver();時,模塊moduleOne必須已經加載已經。如果moduleOneundefined,那麼這是而不是,因爲RequireJS的異步性質,但是因爲在定義moduleOne時存在一個錯誤。例如,如果它輸出值undefined,那麼moduleOne將是未定義的。或者,您可能會得到一個undefinedmoduleOne.whatEver,然後當您嘗試調用它時會導致錯誤,但這會由於例如忘記導出whatEver而導致。

第二種情況和第一種情況之間的區別在於第二種使用CommonJS糖語法,並且這導致上面的第2步有一些額外的處理。之前RequireJS執行出廠它解析函數(如你所提到的),然後處理如同定義已被稱爲像這樣的工廠函數:

define("some_Name", ['require', 'exports', './moduleOne'], function (require, exports) { 

requireexports模塊是由RequireJS內部定義的特殊模塊。請注意RequireJS如何在依賴關係列表的末尾添加./moduleOne。一旦完成,該過程與第一種情況完全相同。

在執行時,模塊已經被加載。那麼這條線所做的只是返回一個對模塊的引用。