You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何映射参数为延迟执行Promise 实现任意层级脚本按序并行加载

脚本分层并行加载实现方案

核心问题原因

你之前的实现无法按预期分层加载,主要是两个问题:

  • Promise热执行特性:只要调用loadScript()返回Promise实例,对应的脚本加载逻辑就会立刻启动,不会等你调用await或.then才执行。原来的抽象代码在遍历层级映射时就调用了所有loadScript,等于所有层级的脚本同时开始加载,自然无法实现分层等待的效果。
  • 原有固定层级代码的隐藏bug:.then(Promise.all(second))写法错误,then必须接收回调函数作为参数,直接传入Promise.all(second)会导致该Promise在同步阶段就运行,两层脚本依然会同时加载,正确写法应为.then(() => Promise.all(second))。

可直接使用的实现(支持任意层级、兼容序号跳号)

这个实现把层级收集、排序、加载逻辑整合,不需要额外的队列预存逻辑,走到对应层级才会触发该层脚本加载,天然满足「同层并行、层间串行」的要求:

function loadScript (script) {
  return new Promise(function(resolve, reject) {
    script.setAttribute("src", script.getAttribute("data-src"));
    script.onload = function() {
      resolve(script.src);
    };
    script.onerror = function() {
      reject(script.src);
    }
  });
}

async function loadScripts() {
  // 收集所有标记了懒加载的脚本
  const allLazyScripts = document.querySelectorAll("script[data-type='lazy'][data-order]");
  // 按data-order值分组
  const hierarchy = new Map();
  allLazyScripts.forEach(script => {
    const order = Number(script.getAttribute("data-order"));
    if (!hierarchy.has(order)) hierarchy.set(order, []);
    hierarchy.get(order).push(script);
  });

  // 按层级序号从小到大排序,兼容跳号、非0/1起始的场景
  const sortedLevels = [...hierarchy.keys()].sort((a, b) => a - b);

  // 逐层加载:当前层全部加载完成后才进入下一层
  for (const level of sortedLevels) {
    const currentLevelScripts = hierarchy.get(level);
    // 仅当遍历到当前层级时,才调用loadScript触发该层脚本加载
    const currentLevelTasks = currentLevelScripts.map(script => loadScript(script));
    await Promise.all(currentLevelTasks);
  }

  console.log('all scripts loaded');
}

// 执行加载,统一捕获加载失败
loadScripts().catch(function(failedScriptSrc) {
  console.log(failedScriptSrc + ' failed to load.');
});

延迟队列写法(如果需要提前定义加载任务)

如果你需要提前把各层加载逻辑存为队列、在需要的时候再启动执行,只需要把每层的加载逻辑包装为返回Promise的函数即可——只有调用函数时才会真正执行loadScript触发加载,不会提前启动:

// 收集、分组、排序层级逻辑和上面一致
const sortedLevels = [...hierarchy.keys()].sort((a, b) => a - b);

// 提前构建任务队列,此时不会触发任何脚本加载
const loadTaskQueue = sortedLevels.map(level => {
  const scripts = hierarchy.get(level);
  // 返回函数而非直接返回Promise,实现延迟执行
  return () => {
    const levelTasks = scripts.map(script => loadScript(script));
    return Promise.all(levelTasks);
  }
});

// 统一的层级遍历执行函数
async function walkHierarchy(taskQueue) {
  for (const runLevelTask of taskQueue) {
    await runLevelTask();
  }
}

// 需要启动加载时调用即可
walkHierarchy(loadTaskQueue)
  .then(() => console.log('all scripts loaded'))
  .catch(failedSrc => console.log(failedSrc + ' failed to load.'));

内容的提问来源于stack exchange,提问作者philolegein

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 19:01:18