使用LABjs的执行顺序错误

Wrong execution order using LABjs

本文关键字:顺序 错误 执行 LABjs 使用      更新时间:2023-09-26

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

  • 由于testLAB.js等待mainCanvas.js,谁等待event .js,我希望警报的顺序是:"events.js" "mainCanvas.js" "testLAB.js"。
  • 然而,我通常得到相反的顺序:"testLAB.js" "mainCanvas.js" "events.js".
  • 有时我得到"testLAB.js" "events.js" "mainCanvas.js".

谁能解释一下?
完整的示例可以在这里下载。

编辑:我使用node.js和http-server模块在本地提供这些页面(如果你想在本地尝试的话)

文件: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/app/testLAB.js

$LAB.setGlobalDefaults({
    BasePath: "/js/",
    Debug:true
});
$LAB
.script("lib/underscore.min.js")
.script("app/mainCanvas.js").wait(function(){
    alert("testLAB.js");
});

文件:js/app/mainCanvas.js

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

文件:js/app/events.js

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

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

如果我使用脚本加载器加载脚本A.js,浏览器将下载并执行该脚本的内容,并且在脚本a中,我使用脚本加载器加载脚本B.js,脚本A.js要求B.js加载的事实并不意味着A.js的"load"事件被神奇地阻止,直到依赖项(即,在这种情况下,B.js)完成加载和执行。

一旦脚本加载完成,浏览器就会立即执行它,一旦主执行完成,浏览器就会在该脚本上触发"load"事件,表明它已经完成。如果该脚本触发了一些其他异步行为,例如加载更多脚本,那么该异步行为将不会对主执行线程或该脚本的"load"事件的触发产生影响。

如果你需要加载嵌套的依赖项,你将需要一个更复杂的系统来"延迟"每个文件的执行,类似于AMD的加载器(如Require.js)如何将所有代码包装在函数中。这种技术起作用的原因是被声明的外部函数的执行顺序是无关的,因为在所有代码定义之后,您可以返回并以各种正确的顺序执行这些函数的有效载荷,并获得您期望的序列。


另一个(更简单的?)选项,这是我个人的做法,如果你不想走AMD/Require路线,就是使用一个简单的构建工具脚本,在构建时读取你的JS文件,发现所有嵌套的依赖关系是什么,并"提升"所有这些,以正确的顺序,到一个单一的"全局"$LAB链调用。所以,在你的文件中,不要用实际的$LAB调用来声明嵌套的依赖关系,而要用依赖关系的符号来表示,就像在JS注释中一样,让你的脚本去查找这些依赖关系。

示例(类似于我自己的做法):

A.js:

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

研究:

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

C.js:

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

不论是:

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

2陈焕祯:

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。