2013-04-12 41 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