如何在loaders.gl的OBJLoader加载Promise完成后导出处理后的myMesh常量
问题一:直接将load返回的Promise赋值给mesh属性的潜在问题
确实存在风险,你现在运行正常只有两种可能:
- 你调用mesh相关逻辑时,刚好异步加载已经完成,且你是通过
await/.then的方式取到了Promise resolve后的真实模型对象 - 你用到的逻辑只接收Promise类型的参数,内部自动做了await处理
潜在问题有两个:
- 如果你同步访问
myMesh.mesh上的模型属性(比如顶点、面数据),会直接拿到undefined,因为Promise本身不存在这些模型专属属性 - 没有做加载错误捕获,如果OBJ文件加载失败、路径错误,
myMesh.mesh会变成rejected状态的Promise,后续用到的地方会直接抛出未捕获的异步异常
问题二:异步加载完成后导出常量的可行方案
你写的导出Promise的写法本身是生效的,所谓“未生效”大概率是你导入后没有用await获取最终结果就直接当对象访问了。这里提供两种常用解决方案:
方案1:导出Promise(兼容性最好)
修正你代码里的拼写错误后即可正常使用:
// 模型模块代码 export const myMeshPromise = load(path_to_obj_file, OBJLoader).then((obj) => { // 注意修正拼写错误:freez→freeze,claculate→calculate return Object.freeze({ mesh: obj, origin: calculateOrigin(obj), dimensions: calculateDim(obj), scale: 1 }); }).catch(err => { // 可以在这里统一处理加载错误 console.error('模型加载失败', err); throw err; });
其他模块导入使用时需要加await:
import { myMeshPromise } from './xxx'; // 只能在async函数内使用 async function useMesh() { const myMesh = await myMeshPromise; // 后续直接操作myMesh的各个属性即可 console.log(myMesh.origin); }
这种方案的优势是兼容性最强,所有支持ES6的环境都可以用,且Promise本身会缓存加载结果,多次await只会发起一次网络请求。
方案2:顶层await(使用最方便)
如果你的运行环境(浏览器≥2021年版本、Node≥14.8)、打包工具(Webpack≥5、Vite、Rollup)支持ES2022的顶层await特性,可以直接导出处理完成的常量:
// 模型模块代码 const obj = await load(path_to_obj_file, OBJLoader); export const myMesh = Object.freeze({ mesh: obj, origin: calculateOrigin(obj), dimensions: calculateDim(obj), scale: 1 });
其他模块导入后可以直接使用,不需要额外await:
import { myMesh } from './xxx'; // 同步即可访问所有属性 console.log(myMesh.dimensions);
额外注意点
你之前取boundingBox的写法有错误,get是Map的方法,需要用圆括号而不是方括号,修正后:
const boundingBox = obj.schema.metadata.get("boundingBox");
内容的提问来源于stack exchange,提问作者YAMI
相关产品推荐
相关产品推荐

