如何在纹理加载完成后正确返回Environment类实例至Main类
解决方案
核心问题是纹理加载是异步操作,你需要让Environment.init返回一个Promise,这样主类可以等待纹理加载完成后再获取实例。以下是修改后的代码和说明:
修改Environment类
class Environment { constructor(params) { this._Init(params); } static init(params) { const getTextures = () => new Promise((resolve, reject)=>{ const manager = new THREE.LoadingManager(()=>resolve(textures)); const loader = new THREE.TextureLoader(manager); // 加载所有纹理,LoadingManager会等全部加载完成后触发回调 const textures = [ './resources/simplex-noise.png', // 其他纹理路径 ].map(filename=>loader.load(filename)); // 添加错误处理,捕获纹理加载失败的情况 manager.onError = (url) => reject(new Error(`纹理加载失败: ${url}`)); }); // 让init方法返回Promise链,最终resolve为Environment实例 return getTextures().then(tex => { // 合并原参数和加载好的纹理,传入构造函数 return new Environment({...params, tex}); }); } _Init(params) { this.params_ = params; // 这里可以直接使用params.tex,比如: // this.textures = params.tex; // 后续初始化逻辑 } }
修改Main类
因为Environment.init现在返回Promise,你需要用async/await或者.then()来接收实例:
class Main { constructor(){ this._Initialize(); } async _Initialize() { //... await this.OnAppStarted_(); //... } async OnAppStarted_() { await this.LoadControllers_(); // 这里可以写依赖this.obj的后续逻辑 } async LoadControllers_() { try { this.obj = await Environment.init({ // 你的参数 }); console.log("Environment实例初始化完成,纹理已全部加载"); } catch (err) { console.error("初始化失败:", err); } } //... }
关键说明
- 让init返回Promise:原代码中
getTextures().then(...)的返回值没有被init方法返回,导致主类无法获取到异步生成的实例。修改后init直接返回这个Promise链,主类可以等待其完成。 - 异步操作的处理:使用
async/await让代码逻辑更清晰,避免回调嵌套;同时添加try/catch捕获加载失败的异常。 - 纹理加载的正确性:Three.js的
LoadingManager会在所有纹理加载完成后触发回调,此时resolve(textures)返回的是已加载完成的纹理对象数组,保证实例化时纹理可用。
内容的提问来源于stack exchange,提问作者Spiri
相关产品推荐
相关产品推荐

