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

BabylonJS同步帧更新函数中如何避免重复调用异步3D Tile加载?

解决BabylonJS帧更新函数重复调用异步Tile加载的问题

你之前尝试给mesh加pending标记的思路没问题,但问题出在初始状态下mesh是null,根本没法挂载任何标记,所以else if分支永远不会触发。换个思路,用类的独立状态变量来跟踪加载状态就行,具体实现如下:

代码示例

原问题代码(简化版)

class TileManager {
  mesh = null;

  // 每帧运行的同步函数
  updateFrame() {
    if (!this.mesh) {
      this.loadTile(); // 每帧都会调用,导致重复加载
    }
  }

  async loadTile() {
    // 异步加载3D Tile的逻辑
    const loadedMesh = await BABYLON.SceneLoader.LoadAssetContainerAsync(...);
    this.mesh = loadedMesh.meshes[0];
  }
}

修改后的代码

class TileManager {
  mesh = null;
  #isLoading = false; // 私有变量,跟踪当前是否正在加载

  updateFrame() {
    // 只有当mesh未加载且未处于加载状态时,才启动加载
    if (!this.mesh && !this.#isLoading) {
      this.#initiateTileLoad();
    }

    // 其他每帧需要执行的逻辑...
  }

  async #initiateTileLoad() {
    this.#isLoading = true;
    try {
      // 执行异步加载逻辑
      const container = await BABYLON.SceneLoader.LoadAssetContainerAsync(...);
      this.mesh = container.meshes[0];
      // 这里可以添加mesh的初始化设置,比如位置、材质等
    } catch (err) {
      console.error("Tile加载失败:", err);
      // 可选:如果加载失败,允许后续重试的话,可以保留mesh为null
      // this.mesh = null;
    } finally {
      // 无论加载成功还是失败,都重置加载状态
      this.#isLoading = false;
    }
  }
}

关键说明

  1. 用独立状态变量替代mesh标记:#isLoading是类的私有变量,不受mesh是否为null的影响,能准确跟踪加载状态
  2. 确保状态重置:用try/finally包裹异步逻辑,保证无论加载成功还是报错,都会把#isLoading设回false,避免永久锁死加载状态
  3. 私有方法封装加载逻辑:把异步加载逻辑放到私有方法#initiateTileLoad里,避免外部直接调用,保证状态变量的一致性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 05:40:32