使用LABjs的执行顺序错误

时间:2013-04-12 14:20:04

标签: javascript labjs

我做了一个非常简单的例子(改编自我的真实项目),它使用LABjs(v2.0.3)加载javascript文件并按给定顺序执行它们。我正在粘贴下面的代码。

  • 由于testLAB.js等待等待events.js的mainCanvas.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在本地提供这些页面(如果你想在本地试用它)

file: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>

file:js / app / testLAB.js

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

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

file:js / app / mainCanvas.js

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

file:js / app / events.js

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

1 个答案:

答案 0 :(得分:3)

这里的问题是对LABjs如何工作的误解,或者更确切地说,是嵌套动态脚本加载的工作方式。

如果我使用脚本加载器加载脚本A.js,浏览器将下载然后执行该脚本的内容,并在脚本A中,我使用脚本加载器加载脚本B.js,事实就是脚本A.js要求加载B.js并不意味着A.js&#34; s&#34;加载&#34;事件被神奇地阻止,直到依赖关系(即在这种情况下,B.js)完成加载和执行。

一旦加载了一个脚本,它就会被浏览器立即执行,一旦主要执行完成,浏览器将触发&#34;加载&#34;该脚本上的事件标志着它完成了。如果该脚本触发了一些其他异步行为,例如加载更多脚本,那么异步行为将对主执行线程没有影响,或者触发该脚本&#34; s&#34; load&#34;事件

如果您需要加载嵌套的依赖项,您将需要一个更复杂的系统&#34; deferring&#34;每个文件的执行,类似于像Require.js这样的AMD加载器如何包装函数中的所有代码。技术工作的原因是声明的外部函数的执行顺序是无关紧要的,因为在定义了所有代码之后,您可以返回并以各种正确的顺序执行这些函数有效负载并获得您期望的序列。


另一个(更简单的?)选项,就是我个人而言,如果你不想进入AMD / Require路线,那就是使用一个简单的构建工具脚本,在脚本中读取你的JS文件时间,发现所有嵌套依赖关系是什么,以及&#34; hoists&#34;所有这些,按照正确的顺序,成为一个全球的&#34; $ LAB连锁电话。所以在你的文件中,不是用实际的$ LAB调用声明嵌套的依赖关系,而是在JS注释中有一个depdendencies的表示法,并让你的脚本寻找那些。

示例(类似于我自己的处理方式):

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。