我有以下功能可以加载给定脚本:
function addScriptTag(url){
var script = document.createElement('script');
script.src = url;
document.getElementsByTagName('head')[0].appendChild(script);
}
我使用该函数来加载彼此相关的库,其中lib2
依赖于lib1
,而lib1
依赖于jquery
:
function loadThemAll(){
addScriptTag('http://path/to/jquery.js');
addScriptTag('http://path/to/lib1.js');
addScriptTag('http://path/to/lib2.js');
}
问题在于,即使按此顺序,当lib1
需要jQuery时,它也找不到。使用lib2
的{{1}}也是如此。
如何使脚本标记创建并顺序加载脚本? 换句话说:
为lib1
添加脚本标签并加载它。
在加载jQuery
时,为jQuery
添加脚本标签并加载它。
在加载lib1
时,为lib1
添加脚本标签并加载它。
答案 0 :(得分:2)
在尝试加载下一个脚本之前,您无需等待上一个脚本的加载,可以尝试使用脚本元素的Promises
和onload
回调。
function addScriptTag(url) {
return new Promise(function (resolve, reject) {
var script = document.createElement('script');
script.onload = resolve;
script.onerror = reject;
script.src = url;
document.getElementsByTagName('head')[0].appendChild(script);
})
}
addScriptTag('http://path/to/jquery.js').then(function() {
return addScriptTag('http://path/to/lib1.js');
}).then(function() {
return addScriptTag('http://path/to/lib2.js');
});
由于将新脚本的onload
方法设置为返回Promise
的{{1}}的解析,因此这将导致脚本等待直到加载前一个脚本为止。
您可以更进一步,并编写一个函数,该函数采用要顺序加载的脚本列表:
addScriptTag
答案 1 :(得分:1)
已addScriptTag
返回一个承诺,该承诺在脚本加载时进行解析,并且await
每次调用:
function addScriptTag(url){
return new Promise((resolve, reject) => {
var script = document.createElement('script');
script.addEventListener('load', resolve);
script.addEventListener('error', reject);
script.src = url;
document.head.appendChild(script);
});
}
async function loadThemAll(){
await addScriptTag('http://path/to/jquery.js');
await addScriptTag('http://path/to/lib1.js');
await addScriptTag('http://path/to/lib2.js');
}
loadThemAll()
.then(() => {
console.log('Everything is loaded!');
})
.catch((err) => {
console.log('There was a problem:', err);
});
您也可以使用async=false
,但这会阻止,直到脚本加载为止,因此可能不是一个好主意:
function addScriptTag(url){
var script = document.createElement('script');
script.setAttribute('async', 'false');
script.src = url;
document.head.appendChild(script);
}
function loadThemAll(){
addScriptTag('http://path/to/jquery.js');
addScriptTag('http://path/to/lib1.js');
addScriptTag('http://path/to/lib2.js');
}
答案 2 :(得分:-1)
您可以将defer
属性添加到脚本中。有关更多详细信息,请参见this question