Javascript 承诺仍然在FireFox中阻止,但不是Chrome?
我制作了一个加载管理器来加载一些对象类。它循环加载函数,直到加载所有内容。这些项目是初始化类(需要很长时间才能完成)的承诺 在chrome中,加载gif是动画,加载不同项目时文本内容会发生变化。 但是,在firefox中,gif没有动画效果,我看到一个弹出窗口,上面写着“网站正在减慢浏览器速度”。(不过文本内容会更新) 我做错了吗?有更好的办法吗 提前谢谢Javascript 承诺仍然在FireFox中阻止,但不是Chrome?,javascript,es6-promise,Javascript,Es6 Promise,我制作了一个加载管理器来加载一些对象类。它循环加载函数,直到加载所有内容。这些项目是初始化类(需要很长时间才能完成)的承诺 在chrome中,加载gif是动画,加载不同项目时文本内容会发生变化。 但是,在firefox中,gif没有动画效果,我看到一个弹出窗口,上面写着“网站正在减慢浏览器速度”。(不过文本内容会更新) 我做错了吗?有更好的办法吗 提前谢谢 const loadManager = { loading: false, loadingItem: -1, //2 load(){
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,
gravity: 12,
atmosphere: true,
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),
random(-1, 1)
).setLength( random( 80000, 300000)),
radius: random(3500, 8000),
gravity: 0,
atmosphere: false,
boulderTexture: new THREE.TextureLoader().load('./resources/boulderGrey.jpg'),
}))
}
resolve();
});
}
}
]
const loadManager={
加载:false,
加载项:-1,//2
加载(){
如果(!this.loading){
//挑选下一项
这个.loadingItem++;
//完成了!
if(this.loadingItem>=this.objects.length){
这个.showPlayButton();
返回;
}
document.getElementById('loadingItem').textContent=this.objects[this.loadingItem].label;
这是。加载=真;
//超时,以便DOM有时间更新“loadingItem”元素中的文本。
设置超时(()=>{
//开始加载新对象
this.objects[this.loadingItem].load().then(this.loading=false);
}, 200);
}
setTimeout(function(){this.load()}.bind(this),2000);
},
showPlayButton(){
if(车辆[0]。对象){
document.getElementById('loadingDiv').style.display='none';
document.getElementById('playButton').style.display='block';
}否则{
log('资产尚未就绪,请在200毫秒后重试');
setTimeout(this.showPlayButton.bind(this),200);
}
},
对象:[
{
标签:“类地行星”,
加载(){
返回新承诺(解决=>{
让EarthColor=[];
earthColors=earthColors.concat(新的三种颜色('darkgreen').toArray());
EarthColor=EarthColor.concat(新的三种颜色('green').toArray());
earthColors=earthColors.concat(新的THREE.Color('darkgrey').toArray());
EarthColor=EarthColor.concat(新的三种颜色('silver').toArray());
EarthColor=EarthColor.concat(新的三种颜色('gold').toArray());
earthColors=earthColors.concat(新的三种颜色('darkcyan').toArray());
天体推送(新行星)({
位置:新的3.Vector3(120000,80000,120000),
半径:80000,
重力:12,
气氛:对,,
颜色:地球颜色,
植被:是的,
boulderTexture:new THREE.TextureLoader().load('./resources/boulderGrey.jpg'),
岩石:'./resources/earthRocks.json',
grassTexture:“./resources/grass.png”
}));
解决();
});
}
},
{
标签:“橙色星球”,
加载(){
返回新承诺(解决=>{
让橙色颜色=[];
orangeColors=orangeColors.concat(新的三种颜色('darkorange').toArray());
orangeColors=orangeColors.concat(新的三种颜色('orange').toArray());
orangeColors=orangeColors.concat(新的三种颜色('darkred').toArray());
orangeColors=orangeColors.concat(新的三种颜色('silver').toArray());
orangeColors=orangeColors.concat(新的三种颜色('gold').toArray());
orangeColors=orangeColors.concat(新的三种颜色('darkcyan').toArray());
天体推送(新行星)({
位置:新的3.矢量3(-240000,-200000,150000),
半径:40000,
重力:12,
气氛:对,,
颜色:橙色,
植被:错,
boulderTexture:new THREE.TextureLoader().load('./resources/boulderRed.jpg'),
rocks:“./resources/redRocks.json”,
grassTexture:“./resources/grassRed.png”
}));
解决();
});
}
},
{
标签:“小行星”,
加载(){
返回新承诺(解决=>{
for(设i=0;i<8;i++){
天体推(新小行星)({
位置:新的3.3矢量(
随机(-1,1),
随机(-1,1),
随机(-1,1)
).setLength(随机(80000,300000)),
半径:随机(3500,8000),
重力:0,
气氛:假,,
boulderTexture:new THREE.TextureLoader().load('./resources/boulderGrey.jpg'),
}))
}
解决();
});
}
}
]
}我会使用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())
}
如果您真的希望遵守承诺,同时也希望保持代码同步,那么您可以这样做
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
进行编写也会更容易。我会使用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())
}
如果你真的想信守诺言