有没有办法等待 THREE.TextureLoader.load() 完成? [英] Is there a way to wait for THREE.TextureLoader.load() to finish?

查看:37
本文介绍了有没有办法等待 THREE.TextureLoader.load() 完成?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 R73 版.我目前的任务是用材料填充数组.这个数组的内容应该在以后使用.那个用法取决于所有材料给我完全加载.

I'm working with release R73. My current task is to fill an array with materials. The content of this array is supposed to be used later. That usage depends on all materials to me completely loaded.

现在我遍历一个 JSON 信息数组并为每个元素调用此代码:

By now I loop through an array of JSON information and call this code for every element:

TLoader.load(
        BASE_ODB_URL + jsonMat.pic,
        function (texture) {
            texture.wrapS = THREE.RepeatWrapping;
            texture.wrapT = THREE.RepeatWrapping;
            texture.repeat.set(jsonMat.scaleu, jsonMat.scalev);
            Mat = new THREE.MeshLambertMaterial({
                    map : texture,
                    side : THREE.DoubleSide,
                    name : jsonMat.mname
                });
            THREEMatList.push(Mat);
        },
        function (xhr) {
        }, //onProgress
            function (xhr) {
            Mat = new THREE.MeshLambertMaterial({
                    color : 0xff0000,
                    side : THREE.DoubleSide,
                    name : jsonMat.mname
                });
            THREEMatList.push(Mat);
        } 
    )

TLoader 提前初始化:var TLoader = new THREE.TextureLoader();

TLoader is initialized earlier: var TLoader = new THREE.TextureLoader();

如果没有材料,当需要时,我会得到备用材料.这只是作为一个错误选项.有没有办法等到 .load() 完成?

If a material isn't there, when it is needed, I get a fallback material. This was only intended as an error option. Is there a way to wait until .load() finishes?

推荐答案

解决这个问题的方法是通过 Promise 因为它们确实是前进的方向,我个人认为 TextureLoader 没有返回 Promise 开始(它会使这更容易一些).但是,请记住,IE11 将需要一个 polyfill,因为它缺乏对 Promise 的原生支持.

A way to solve this is through Promise's as they are really the way forward and I personally think it's a shame TextureLoader doesn't return a Promise to start with (it would make this a little bit easier). However, do keep in mind that IE11 will need a polyfill as it lacks native support for promises.

应该这样做,其中 textureArray 在可迭代的 Array 中表示您的 JSON 数据:

Something like this should do it, where textureArray represents your JSON data in an iterable Array:

var allPromises = [];

textureArray.forEach( function( jsonMat ) {

    allPromises.push( new Promise( function( resolve, reject ) {

        TLoader.load(
           BASE_ODB_URL + jsonMat.pic,

           function( texture ) {
               // Success callback of TextureLoader
               texture.wrapS = THREE.RepeatWrapping;
               texture.wrapT = THREE.RepeatWrapping;
               texture.repeat.set( jsonMat.scaleu, jsonMat.scalev );
               var material = new THREE.MeshLambertMaterial({
                   map: texture,
                   side: THREE.DoubleSide,
                   name: jsonMat.mname
               });
               THREEMatList.push( material );

               // We're done, so tell the promise it is complete
               resolve( material );
           },

           function( xhr ) {
               // Progress callback of TextureLoader
               // ...
           },

           function( xhr ) {
               // Failure callback of TextureLoader
               // Reject the promise with the failure
               reject( new Error( 'Could not load ' + jsonMat.pic ) );
           }
        );

    }));

});

Promise.all( allPromises )
    .then( function( arrayOfMaterials ) {
        // All textures are now loaded, and this array
        // contains all the materials that you created
    }, function( error ) {
        console.error( "Could not load all textures:", error );
    });

所以这里发生的事情是一个总体Promise 用于跟踪其他Promise 的状态.每个被加载的纹理都被包裹在一个 Promise 中,它被添加到 allPromises 中.最后,测试整个 Promise 集的成功或失败,然后您就知道整体的成功或失败.

So what's happening here is that one overarching Promise is used to keep track of the status of the other Promises. Each texture being loaded is wrapped in a Promise, which are added to allPromises. Finally that entire set of promises is tested for success or failure, and at that point you know about the overall success or failure.

这里要记住的一件重要的事情是 Promise.all 只会在 all 纹理被加载后才会成功,并且一旦有任何一个它就会失败失败.如果您需要更精细的控制,您将需要一个 Promise polyfill,其功能比 Promise/A+ 规范提供的更多,例如 RSVP.js.或者,您可以 resolve() 它并优雅地处理结果,而不是 reject()ing 承诺.

One important thing to keep in mind here is that the Promise.all will only succeed if all the textures were loaded, and it will fail as soon as any one fails. If you need finer control than that you'll need a Promise polyfill with more features than the Promise/A+ spec offers, such as RSVP.js. Or instead of reject()ing the promise you could resolve() it and handle the result gracefully.

这篇关于有没有办法等待 THREE.TextureLoader.load() 完成?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆