我有一个基本的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 [email protected] 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
...)脚本在随机顺序加载所以,有时我得到了经典:
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
但说实话感觉太肮脏走这条路,所以我想知道是否也许有人有更好的主意......
使用AMD我不是假设你的选择吗?其他一切可能会影响性能。但方法很清楚:构建一个依赖关系图并进行处理。动态添加的脚本在不同的浏览器中执行的方式不同。但是他们可能会执行'async',所以无法控制它。 – Lux
嗨@Lux,我不熟悉AMD。你能提供一些文件的链接吗? –