2013-04-12 54 views
2

我做了一個非常簡單的例子(改編自我的真實項目),它使用LABjs(v2.0.3)加載javascript文件並按給定順序執行它們。我正在粘貼下面的代碼。錯誤的執行順序使用LABjs

  • 由於testLAB.js等待mainCanvas.js,誰events.js等待,我希望警報的順序是: 「events.js」 「mainCanvas.js」 「testLAB.js」。
  • 但是,我通常得到相反的順序:「testLAB.js」「mainCanvas.js」「events.js」。
  • 有時我會得到「testLAB.js」「events.js」「mainCanvas.js」。

有人可以解釋嗎?
完整的示例可以下載here

編輯:我如何使用Node.js和http-server module在本地提供這些網頁(如果你想嘗試一下當地以及)

文件:index.html的

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <title>Test lab.js</title> 
    <script src="js/lib/LAB.js"></script> 
    <script src="js/app/testLAB.js"></script> 
</head> 
<body> 
</body> 
</html> 

文件:JS /應用/ testLAB.js

$LAB.setGlobalDefaults({ 
    BasePath: "/js/", 
    Debug:true 
}); 

$LAB 
.script("lib/underscore.min.js") 
.script("app/mainCanvas.js").wait(function(){ 
    alert("testLAB.js"); 
}); 

文件:JS /應用/ mainCanvas.js

$LAB 
.script("lib/jquery.js").wait() 
.script("lib/underscore.min.js") 
.script("app/events.js") 
.wait(function() { 
    alert("mainCanvas.js"); 
}); 

文件:JS /應用/ events.js

$LAB 
.script("lib/jquery.js") 
.script("lib/underscore.min.js") 
.wait(function() { 
alert("events.js"); 
}); 

回答

2

這裏的問題是LABjs如何工作的,或者說,如何嵌套的動態腳本加載作品的誤解。

如果使用腳本加載程序加載腳本A.js,瀏覽器將下載並執行該腳本的內容,並在腳本A內部使用腳本加載器加載腳本B.js,腳本A.js要求B.js加載並不意味着A.js的「加載」事件被神奇地阻塞,直到依賴關係(即本例中爲B.js)完成加載和執行。

一旦腳本加載完畢,它會立即被瀏覽器執行,並且一旦其主執行完成,瀏覽器就會觸發該腳本上的「加載」事件,表明它已完成。如果該腳本引發了一些其他異步行爲(例如加載更多腳本),那麼異步行爲將不會影響主執行線程或觸發該腳本的「加載」事件。

如果您需要加載嵌套的依賴關係,您需要一個更復雜的系統來「推遲」每個文件的執行,類似於AMD的加載程序(如Require.js)將所有代碼包含在函數中。技術工作的原因是被聲明的外部函數的執行順序是不相關的,因爲在所有的代碼被定義之後,你可以返回並按照各種正確的順序執行這些函數有效載荷,並獲得你期望的順序。


其他(簡單?)選項,這是我親手做的,如果你不想去的AMD /要求的路線,就是用一個簡單的構建工具腳本,通過你的JS文件中讀取在構建時,發現所有嵌套的依賴關係是什麼,並以正確的順序將所有這些依賴關係「提升」爲單個「全局」$ LAB鏈調用。因此,在您的文件中,不要使用實際的$ LAB調用聲明嵌套的依賴關係,而只需記錄depdendencies,就像在JS註釋中一樣,並讓腳本查找它們。

實例(類似我怎麼做的事情我自己):

A.js:

// needs "B.js" 
// needs "C.js" 

A.something = function(/*..*/) { /*..*/ };  
B.something(); 
C.something(); 

B.js:

// needs "D.js" 

B.something = function(/*..*/) { /*..*/ }; 
D.something(); 

C.js:

// needs "D.js" 
// needs "E.js" 

C.something = function(/*..*/) { /*..*/ }; 
D.something(); 
E.something(); 

D.js:

D.something = function(/*..*/) { /*..*/ }; 

E.js:

E.something = function(/*..*/) { /*..*/ }; 

然後,我有一個簡單的腳本看起來通過我的文件,並發現使所有相關性滿足必要的執行順序。

然後它產生在我的主頁使用單個$ LAB鏈,看起來像這樣:

$LAB 
.script("D.js") 
.script("E.js").wait() // D and E can execute in either order 
.script("B.js") 
.script("C.js").wait() // B and C can execute in either order 
.script("A.js") 
.wait(function(){ 
    alert("Everything is loaded!"); 
}); 

唯一要注意像我建議的方法是,你不能做圓周依賴關係(如C取決於B和B取決於C)。如果你需要循環依賴,請去AMD/Require.js。

+0

非常感謝,我現在能夠解決我的問題! – mnieber