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

React useEffect调用回调函数获取BIM属性时setState偶发无响应问题

问题根因

该偶发问题是异步时序不匹配导致的:

  • model.getProperties 是Autodesk Viewer提供的异步API,调用后不会立刻返回结果
  • 你在循环中批量触发了大量属性查询请求,还未等所有请求执行完成、所有属性都写入histogram对象,就提前调用cb(histogram)返回了结果
  • 刷新页面后表现正常,是因为模型数据、接口响应被浏览器缓存,异步请求返回速度变快,刚好在回调触发前所有查询都已执行完成

修复方案

将回调式写法改造为Promise异步等待写法,确保所有属性查询完成后再返回结果:

第一步:改造getAllLeavesProperties方法

//Get All Leavs Props
export const getAllLeavesProperties = (
  allModels: Autodesk.Viewing.GuiViewer3D | undefined
): Promise<Record<string, any>> => {
  // histogram放到函数内部,避免外部变量污染导致的历史数据干扰
  const histogram: Record<string, any> = {}
  const allLoadedViewers = isolateAndColorObject(
    allModels as Autodesk.Viewing.GuiViewer3D
  );
  // 外层先等待dbId获取完成
  return new Promise((resolve) => {
    getAllLeavesDbId(allModels, (dbId: number[]) => {
      // 收集所有属性查询的Promise
      const propertyPromises: Promise<void>[] = []
      dbId.forEach((id) => {
        if (allLoadedViewers && id) {
          for (let model of allLoadedViewers) {
            if (model) {
              // 把每个getProperties调用包装成Promise,放到数组里统一等待
              const pro = new Promise<void>((res) => {
                model.getProperties(id, (props) => {
                  for (let prop of props.properties) {
                    if (!prop) return;
                    if (!histogram[prop.displayName]) {
                      histogram[prop.displayName] = {};
                    }
                    if (!histogram[prop.displayName][prop.displayValue]) {
                      histogram[prop.displayName][prop.displayValue] = [];
                    }
                    histogram[prop.displayName][prop.displayValue].push(props.dbId);
                  }
                  res()
                })
              })
              propertyPromises.push(pro)
            }
          }
        }
      });
      // 等待所有属性查询完成后,再返回最终的histogram
      Promise.all(propertyPromises).then(() => resolve(histogram))
    });
  })
};

第二步:改造调用逻辑

const test = async () => {
  if (!allModels) return;
  try {
    const data = await getAllLeavesProperties(allModels)
    const BIM7AATypeComments = data["BIM7AATypeComments"];
    if (BIM7AATypeComments) {
      const label = Object.keys(BIM7AATypeComments);
      if (label) setTt(label);
      const myObject = Object.keys(BIM7AATypeComments).map(
        (key) => BIM7AATypeComments[key].length
      );
      if (myObject) setrr(myObject);
    }
  } catch (error) {
    console.log(error)
  }
};

React.useEffect(() => {
  let isMounted = true
  // 加组件卸载判断,避免组件销毁后setState引发的内存泄漏警告
  if (isMounted) {
    test();
  }
  return () => {
    isMounted = false
  }
}, [allModels]); // 把allModels加到依赖项里,模型加载完成后自动重新触发查询

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 23:18:04