添加脚本标签并按顺序加载脚本

时间:2019-08-26 22:46:59

标签: javascript

我有以下功能可以加载给定脚本:

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添加脚本标签并加载它。

3 个答案:

答案 0 :(得分:2)

在尝试加载下一个脚本之前,您无需等待上一个脚本的加载,可以尝试使用脚本元素的Promisesonload回调。

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