2

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」が出てきます。

誰でも説明できますか?完全な例は、ここから
ダウンロードできます。

編集: 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");
});
4

1 に答える 1

3

ここでの問題は、LABjs がどのように機能するか、またはネストされた動的スクリプトのロードがどのように機能するかについての誤解です。

スクリプト ローダーを使用してスクリプト A.js を読み込むと、ブラウザーはそのスクリプトの内容をダウンロードして実行し、スクリプト A 内でスクリプト ローダーを使用してスクリプト B.js を読み込みます。 B.js の読み込みを要求されても、依存関係 (つまり、この場合は B.js) の読み込みと実行が完了するまで、A.js の「読み込み」イベントが魔法のようにブロックされるわけではありません。

スクリプトがロードされると、ブラウザによってすぐに実行され、メインの実行が終了すると、ブラウザはそのスクリプトで「ロード」イベントを発生させ、完了したことを知らせます。そのスクリプトが、他のスクリプトの読み込みなど、他の非同期動作を開始した場合、その非同期動作は、メイン実行スレッドまたはそのスクリプトの「ロード」イベントの発生に影響を与えません。

ネストされた依存関係をロードする必要がある場合は、Require.js などの AMD ローダーがすべてのコードを関数でラップするのと同様に、各ファイルの実行を「延期」するより洗練されたシステムが必要になります。この手法が機能する理由は、宣言されている外部関数の実行順序が無関係であるためです。すべてのコードが定義された後、戻ってそれらの関数ペイロードをさまざまな正しい順序で実行し、期待どおりのシーケンスを取得できるためです。


もう 1 つの (より単純な?) オプションは、AMD/Require ルートに行きたくない場合に私が個人的に行っていることですが、ビルド時に JS ファイルを読み取る単純なビルド ツール スクリプトを使用することです。ネストされた依存関係は、単一の「グローバル」$LAB チェーン呼び出しに正しい順序で「ホイスト」されます。そのため、ファイル内で、実際の $LAB 呼び出しでネストされた依存関係を宣言する代わりに、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 に移動します。

于 2013-04-12T17:20:52.180 に答える