js 的同步加载

js的同步加载

在浏览器环境中,动态加载脚本(如通过 document.createElement('script')​)是异步的,无法直接改为同步执行。这是因为浏览器的设计决定了脚本加载必须是异步的,以避免阻塞页面渲染和其他操作。

不过,如果你需要实现类似“同步加载”的效果,可以通过以下方法模拟:


方法 1:使用 async: false​ 的 XMLHttpRequest​ 或 fetch

通过 XMLHttpRequest​ 或 fetch​ 同步加载脚本内容,然后将其注入到页面中。

示例代码:

function loadScriptSync(src) {
  const xhr = new XMLHttpRequest();
  xhr.open('GET', src, false); // 同步请求
  xhr.send(null);

  if (xhr.status === 200) {
    const script = document.createElement('script');
    script.textContent = xhr.responseText;
    document.head.appendChild(script);
  } else {
    throw new Error(`Failed to load script: ${src}`);
  }
}

// 使用
loadScriptSync('/aaa.js');
console.log('Script loaded synchronously');

注意:

  • xhr.open​ 的第三个参数设置为 false​,表示同步请求。
  • 同步请求会阻塞页面渲染,可能导致页面卡顿,不推荐在现代浏览器中使用。

方法 2:使用 defer​ 或模块化加载

如果目标是确保脚本按顺序执行,可以使用 defer​ 属性或 ES 模块化加载。

示例代码:

const script = document.createElement('script');
script.src = '/aaa.js';
script.defer = true; // 确保脚本按顺序执行
document.head.appendChild(script);

script.onload = () => {
  console.log('Script loaded and executed in order');
};

注意:

  • defer​ 属性会确保脚本在文档解析完成后按顺序执行。
  • 这种方法不会阻塞页面渲染。

方法 3:使用 Promise​ 和 async/await

通过 Promise​ 和 async/await​ 模拟同步行为。

示例代码:

function loadScriptAsync(src) {
  return new Promise((resolve, reject) => {
    const script = document.createElement('script');
    script.src = src;
    script.onload = resolve;
    script.onerror = reject;
    document.head.appendChild(script);
  });
}

(async () => {
  await loadScriptAsync('/aaa.js');
  console.log('Script loaded and executed');
})();

注意:

  • 这种方法不会阻塞页面渲染,但可以确保脚本加载完成后再执行后续代码。

方法 4:直接嵌入脚本

如果脚本内容较小,可以直接将脚本内容嵌入到页面中。

示例代码:

const scriptContent = `
  console.log('This script is embedded directly');
  // 这里是脚本内容
`;

const script = document.createElement('script');
script.textContent = scriptContent;
document.head.appendChild(script);

注意:

  • 这种方法适用于脚本内容较小且不需要从外部加载的情况。

总结

  • 无法直接同步加载:浏览器不允许直接同步加载外部脚本。

  • 替代方案

    • 使用 XMLHttpRequest​ 同步加载(不推荐,会阻塞页面)。
    • 使用 defer​ 或模块化加载(推荐)。
    • 使用 Promise​ 和 async/await​ 模拟同步行为(推荐)。
    • 直接嵌入脚本内容(适用于小脚本)。

image.png

留下你的脚步
推荐阅读