[英]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.com
, example.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.js
或require.js
這樣的加載器基本上會構建這些模塊的圖形,然后當您執行諸如require('mymodule')
,它將知道必須先調用dep
,然后將結果注入將mymodule
作為第一個參數。
loader.js
基本上只會執行此操作,而require.js
可以通過網絡加載模塊。
但是,通過這兩種方法,您都可以手動加載腳本標簽,等待所有標簽加載完畢,然后調用入口點。
重要的是, define
調用的執行順序無關緊要。
一種解決方案是創建捆綁包,只需將要同時加載的所有依賴項連接到一個縮小的js文件中,即“捆綁包”。 加載該文件而不是3。它將解決您的依賴順序問題,並提供其他改進。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.