如何实现GLTF文件拖拽上传的异步加载,与URL加载逻辑统一
本地GLTF文件拖拽异步加载与远程加载统一实现
问题说明
已有可正常运行的异步函数loadGLTFUrl,支持从远程URL加载GLTF模型并为对象添加元数据。现在需要实现本地GLTF文件拖拽加载的异步函数,要求该函数能和loadGLTFUrl一同加入Promise数组,通过Promise.all统一处理返回的GLTF对象,无需区分模型来源。
正确的loadGLTFFileObject实现
要实现符合要求的异步函数,需要将FileReader读取文件和GLTFLoader.parse解析模型这两个异步操作都包装进Promise中,同时处理错误场景,并为加载后的GLTF对象添加元数据。代码如下:
// 现有正常运行的远程加载函数 async function loadGLTFUrl(data) { try { const result = await getGLTFLoader().loadAsync(data.url); result.scene.userData = data; return result; } catch (error) { console.error('远程GLTF加载失败:', error); throw error; // 抛出错误让Promise.all捕获 } } // 实现本地文件异步加载的函数 async function loadGLTFFileObject(data) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => { // 调用GLTFLoader解析ArrayBuffer getGLTFLoader().parse( reader.result, '', (gltf) => { // 添加元数据 gltf.scene.userData = data; resolve(gltf); }, (error) => { console.error('GLTF解析失败:', error); reject(error); } ); }; reader.onerror = (error) => { console.error('文件读取失败:', error); reject(error); }; // 以ArrayBuffer格式读取本地文件 reader.readAsArrayBuffer(data.fileobject); }); }
统一调用示例
两个函数可以直接加入Promise数组,通过Promise.all统一处理加载结果:
const promises = []; promises.push(loadGLTFUrl({ url: 'https://example.com/model.gltf', /* 其他元数据 */ })); promises.push(loadGLTFFileObject({ fileobject: 拖拽得到的File对象, /* 其他元数据 */ })); Promise.all(promises) .then((loaded_gltfs) => { loaded_gltfs.forEach((gltf) => { // 统一处理GLTF对象,无需区分来源 console.log('加载完成的模型:', gltf.scene); console.log('模型元数据:', gltf.scene.userData); }); }) .catch((error) => { console.error('部分模型加载失败:', error); });
你的尝试版本修正
你提供的尝试版本存在几个需要修正的点:
- 未处理
FileReader和GLTFLoader的错误场景,一旦出错会导致Promise无法被reject - 没有为加载后的GLTF对象添加元数据,不符合业务需求
- 参数设计和
loadGLTFUrl不一致,建议统一接收包含文件对象和元数据的data参数 resolve(gltf, null, reject)的写法错误,resolve只需要传入成功结果
修正后的版本如下:
function loadGLTFFromFileObject(data) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => { getGLTFLoader().parse( reader.result, '', (gltf) => { gltf.scene.userData = data; // 添加元数据 resolve(gltf); }, (parseError) => reject(parseError) // 处理解析错误 ); }; reader.onerror = (readError) => reject(readError); // 处理文件读取错误 reader.readAsArrayBuffer(data.fileobject); }); }
内容的提问来源于stack exchange,提问作者Molly Birk
相关产品推荐
相关产品推荐

