Promise仍在FireFox中阻止,但在Chrome中却没有?

我做了一个加载管理器,可以加载一些对象类。它循环加载功能,直到所有内容都加载完毕。这些项目是对初始化类的承诺(需要很长时间才能完成)。

在chrome中可以正常工作,加载gif时会设置动画,并且加载不同项目时textContent会更改。 但是,在firefox中,gif并未进行动画处理,并且出现了一个弹出式窗口,提示“网站正在降低浏览器的速度”。(虽然textContent确实会更新)。

我做错了吗?有更好的方法吗?

谢谢。

const loadManager = {
loading: false,loadingItem: -1,//2
load(){
    if (!this.loading){
        //pick next item
        this.loadingItem++;

        //DONE!
        if(this.loadingItem >= this.objects.length){
            this.showPlayButton();
            return;
        }

        document.getElementById('loadingItem').textContent = this.objects[this.loadingItem].label;
        this.loading = true;

        //a timeout to give the DOM time to update the text in the 'loadingItem' element.
        setTimeout( ()=>{
            //start loading new object
            this.objects[this.loadingItem].load().then( this.loading = false );
        },200);
    }

    setTimeout(function(){this.load()}.bind(this),2000);
},showPlayButton(){

    if ( vehicles[0].object ){
        document.getElementById('loadingDiv').style.display = 'none';                
        document.getElementById('playButton').style.display = 'block';
    } else {
        console.log('assets not ready yet,trying again in 200ms');
        setTimeout(this.showPlayButton.bind(this),200);
    }

},objects:[
    {
        label: 'Earthlike planet',load(){
            return new Promise( resolve =>{
                let earthColors = [];
                earthColors = earthColors.concat( new THREE.Color('darkgreen').toArray() );
                earthColors = earthColors.concat( new THREE.Color('green').toArray() );
                earthColors = earthColors.concat( new THREE.Color('darkgrey').toArray() );
                earthColors = earthColors.concat( new THREE.Color('silver').toArray() );
                earthColors = earthColors.concat( new THREE.Color('gold').toArray() );
                earthColors = earthColors.concat( new THREE.Color('darkcyan').toArray() );
                celestialObjects.push(new Planet({
                    position: new THREE.Vector3(120000,80000,120000),radius: 80000,gravity: 12,atmosphere: true,colors: earthColors,vegetation: true,boulderTexture: new THREE.TextureLoader().load('./resources/boulderGrey.jpg'),rocks: './resources/earthrocks.json',grassTexture: './resources/grass.png'
                }));

                resolve();
            });
        }
    },{
        label: 'Orange planet',load(){
            return new Promise( resolve =>{
                let orangeColors = [];
                orangeColors = orangeColors.concat( new THREE.Color('darkorange').toArray() );
                orangeColors = orangeColors.concat( new THREE.Color('orange').toArray() );
                orangeColors = orangeColors.concat( new THREE.Color('darkred').toArray() );
                orangeColors = orangeColors.concat( new THREE.Color('silver').toArray() );
                orangeColors = orangeColors.concat( new THREE.Color('gold').toArray() );
                orangeColors = orangeColors.concat( new THREE.Color('darkcyan').toArray() );
                celestialObjects.push(new Planet({
                    position: new THREE.Vector3(- 240000,-200000,150000),radius: 40000,colors: orangeColors,vegetation: false,boulderTexture: new THREE.TextureLoader().load('./resources/boulderRed.jpg'),rocks: './resources/redrocks.json',grassTexture: './resources/grassRed.png'
                }));

                resolve();
            });
        }
    },{
        label: 'Asteroids',load(){
            return new Promise( resolve =>{
                for (let i = 0; i < 8; i ++){
                    celestialObjects.push( new Asteroid({
                        position: new THREE.Vector3(
                            random(-1,1),random(-1,1)
                        ).setLength( random( 80000,300000)),radius: random(3500,8000),gravity: 0,atmosphere: false,}))
                }

                resolve();
            });
        }
    }
]

}

dalanmao007 回答:Promise仍在FireFox中阻止,但在Chrome中却没有?

我将使用Promise.all进行某些操作,并避免使用setTimeout和递归函数,除非您想同步加载它们,否则这将首先使用Promises达到目的。

使用诺言,我会做这样的事情。尽管这会异步加载所有内容。

load(){
if (!this.loading){
    //DONE!
    const psArr = []
    for(const obj in this.objects){
        const ps = obj.load()
        psArr.push(ps)
    }
    Promise.all(psArr).then(() => this.showPlayButton())
}

如果您确实希望保留Promises,但又希望保持代码同步,则可以执行以下操作。

load(){
if (!this.loading){
    //DONE!
    const psArr = [Promise.resolve()]
    let i = 0
    for(const obj in this.objects){
        const previous = psArr[i] 
        // first array element is a promise object that is already resolved
        previous.then(() => {
           //you can add your label changes inside this block.
           const ps = obj.load()
           psArr.push(ps)
        })
        // the obj.load() will now only run everytime the previous promise is resolved. 
        i++
    }
    // promise.all still works for this case
    Promise.all(psArr).then(() => this.showPlayButton())
}

使用async/await

编写起来也更容易
本文链接:https://www.f2er.com/2791238.html

大家都在问