2016-12-01 15 views
0

私は基本的にSPAを持っており、必要に応じていくつかの資産(主にスタイルシートやスクリプト)を読み込みます。私はModuleXをロードする必要があるとき私は、そう動的に読み込まれたスクリプトの読み込み順序の制御

class ModuleXLoader 
    constructor: -> 
     @scripts = [ 
      'https://www.example.com/assets/js/script1.js', 
      'https://www.example.net/assets/js/script2.js', 
      'https://www.example.org/assets/js/script3.js' 
     ] 
     @scriptsLoaded = 0 

    load: (@callback) -> 
     document.head.appendChild @.scriptTag url for url in @scripts 

    scriptTag: (url) -> 
     domElement = document.createElement 'script' 
     domElement.type = 'text/javascript' 
     domElement.onload = (event) => 
      console.log event.currentTarget.srC# This logs the script's URL 
      @.callback() if [email protected] is @scripts.length and typeof @callback is 'function' 
     domElement.src = url 
     return domElement 

loader = new ModuleXLoader() 
loader.load() => 
    console.log 'All scripts have been loaded, let\'s do stuff!' 

これは私の<head>に必要なスクリプトを追加し

ローダは、この(これは簡易版である)のように見えますすべてが期待通りに機能します。


問題は必要なスクリプトの間にいくつかの依存関係が存在する場合に表示されます。すべてのCDNスクリプトそうランダム順にロードされている(...さんはexample.comexample.netを言わせて)は、の応答時間に応じて、時々私は古典を得た:もちろん

Uncaught ReferenceError: ModuleXDependency is not defined

、私は私の上の異なるordenationsを試してみました@scripts配列ですが、それはできません。多分誰かが良いアイデアを持っている場合

@scripts = 
    script1: 
     url: 'https://www.example.com/assets/js/script1.js' 
     requires: 'script3' 
     loaded: false 
    script2: # etc. 


domElement.onload = (event) => 
    # This is not a real implementation but kind of pseudocode idea... 
    @wait() while not @scripts[@scripts['script1'].requires].loaded 

しかし、正直に言うと、それはこの道を行くにはあまりにも汚い感じているので、私は思っていた...:

私はセマフォ実装のいくつかの種類に考えていました

+0

AMDを使用するのはあなたの選択肢ではありません。おそらく他のすべてがパフォーマンスに影響を与えます。しかし、その方法は明らかです。依存グラフを作成し、それを処理します。動的に追加されたスクリプトは、ブラウザごとに異なる方法で実行されます。しかし、彼らは '非同期'を実行するかもしれないので、それを制御する方法はありません。 – Lux

+0

こんにちは@Lux、私はAMDに精通していない。いくつかのドキュメントへのリンクを提供してください。 –

答えて

3

AMDのようなモジュール定義を使用することをお勧めします。おそらく、requirejsのような既存のモジュールローダーを使用することを検討するべきでしょう。ここでは、AMDに関するドキュメントもご覧いただけます。たぶんwhyAMDのテキストを読んでください。

最低限のローダが必要な場合は、チェックアウト可能なスクリプトを自分でロードする場合はloader.jsです。

AMDについての考えは、あなたがこのようなあなたのモジュールを定義することを基本的には次のとおりです。

define('dep', [], function() { 
    // here goes your code 
    return {}; 
}); 

define('mymodule', ['dep'], function(dep) { 
    // here goes your code. 
}); 

loader.jsまたはrequire.jsなどのローダは基本的に、これらのモジュールのグラフを構築する、とあなたはrequire('mymodule')ような何かをするとき、それ意志最初にdepを呼び出してから、結果を最初のパラメータとしてmymoduleに注入する必要があることがわかります。

loader.jsrequire.jsは、モジュールをネットワーク経由でロードする機能を備えていますが、基本的にはこれを実行します。

両方とも、スクリプトタグを手動でロードしてすべてがロードされるまで待ってから、エントリポイントを呼び出すことができます。

defineへの呼び出しが実行される順序は関係ありません。

1

1つの解決策は、バンドルを作成し、同時にロードするすべての依存関係を1つの縮小jsファイル「連結」に連結することです。 3つではなく1つのファイルを読み込んで、依存関係の順序問題を解決し、他の改良点も提供します。

+0

あなたはそうです。これは可能な解決策です。とにかく、これが別の方法でできるかどうかを知りたいです...ありがとう! –

関連する問題