You need to enable JavaScript to run this app. Three.js GLTF加载场景下Promise.all未等待所有任务完成提前触发
优惠活动
大模型
产品
解决方案
定价
更多

Three.js GLTF加载场景下Promise.all未等待所有任务完成提前触发

问题核心原因
  • processTransformModel 函数未将内部创建的Promise链返回到外部,调用时返回值为undefined,导致push到promises数组的并非可跟踪的Promise实例
  • 返回的Promise链未等待GLTF资源实际加载完成,只要走到发起加载请求的步骤就会被提前标记为resolved
    1. 内层Promise的.then回调中调用gltfLoader.load时,没有将该异步加载操作的结果返回到Promise链中,回调执行完就会直接触发外层Promise的resolve,完全不等GLTF加载结束
    2. 非zip分支存在笔误:resolve(url) 中的url未定义,实际应为resolve(model.url)
    3. gltfLoader.load本身是异步方法,其加载完成、加载失败的逻辑没有被纳入Promise跟踪范围,导致Promise.all判定所有任务完成时,实际仍有大体积模型在加载过程中
修复方案

首先调整processTransformModel函数,完整返回带有错误捕获的Promise链,确保每一步异步操作都被正确跟踪:

function processTransformModel(model) {
  // 第一步:解析得到实际的gltf/glb文件路径
  return new Promise((resolve, reject) => {
    if (model.url.match(/\.zip$/)) {
      new THREE.ZipLoader().load(model.url)
        .then(zip => {
          manager.setURLModifier(zip.urlResolver);
          const gltfPath = zip.find(/\.(gltf|glb)$/i)[0];
          resolve(gltfPath);
        })
        // 将zip加载的错误传递到外层Promise,避免未捕获错误
        .catch(reject);
    } else {
      // 修复原笔误,使用入参model的url
      resolve(model.url);
    }
  })
  // 第二步:返回gltf加载的Promise,让链等待加载完成
  .then(file => {
    // 使用GLTFLoader内置的loadAsync方法,直接返回Promise,自动跟踪加载状态、捕获错误
    return gltfLoader.loadAsync(file);
  })
  .then(gltf => {
    // 在此处执行对gltf对象的原有操作
    return gltf;
  });
}

其次调整原有Promise.all的回调逻辑:

  • 修复Promise链后,Promise.all的then回调触发时已经代表所有GLTF模型加载完成,可直接在回调中执行loadAttachModels(),无需再通过manager.onLoad绑定回调,避免绑定时机晚于LoadingManager触发onLoad的问题:
Promise.all(promises)
  .then(() => {
    loadAttachModels();
  })
  .catch(e => {
    // 原有错误处理逻辑
  });

注:如果必须依赖LoadingManager的onLoad回调,需要在所有加载发起前完成manager.onLoad的绑定,避免绑定时机过晚导致回调不触发。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 09:54:04