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

如何实现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);
    });

你的尝试版本修正

你提供的尝试版本存在几个需要修正的点:

  1. 未处理FileReader和GLTFLoader的错误场景,一旦出错会导致Promise无法被reject
  2. 没有为加载后的GLTF对象添加元数据,不符合业务需求
  3. 参数设计和loadGLTFUrl不一致,建议统一接收包含文件对象和元数据的data参数
  4. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 08:40:55