簡體   English   中英

控制動態加載腳本的加載順序

[英]Controlling load order on dynamically loaded scripts

我有一個基本的SPA ,可以按需加載一些資產(主要是樣式表和腳本)。

加載程序如下所示(這是簡化版本):

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 ++@scriptsLoaded is @scripts.length and typeof @callback is 'function'
        domElement.src = url
        return domElement

因此,當我需要加載ModuleX我會執行以下操作:

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

這會將所需的腳本附加到我的<head>並且一切正常。


當所需腳本之間存在某些依賴關系時,將出現問題 根據每個CDN(例如example.comexample.net ...)的響應時間,腳本以隨機順序加載,因此,有時我會得到經典的腳本:

未捕獲的ReferenceError: 未定義ModuleXDependency

當然,我在我的@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

但是老實說,這樣下去感覺太臟了,所以我想知道也許有人有更好的主意...

我的建議是使用類似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.jsrequire.js這樣的加載器基本上會構建這些模塊的圖形,然后當您執行諸如require('mymodule') ,它將知道必須先調用dep ,然后將結果注入將mymodule作為第一個參數。

loader.js基本上只會執行此操作,而require.js可以通過網絡加載模塊。

但是,通過這兩種方法,您都可以手動加載腳本標簽,等待所有標簽加載完畢,然后調用入口點。

重要的是, define調用的執行順序無關緊要。

一種解決方案是創建捆綁包,只需將要同時加載的所有依賴項連接到一個縮小的js文件中,即“捆綁包”。 加載該文件而不是3。它將解決您的依賴順序問題,並提供其他改進。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM