我需要进行大量计算。因此,我参考here创建一个简单的加载屏幕。不幸的是,计算完成后会显示加载屏幕。
这是我的代码
class RosterScheduler
{
.........................
autoAssign()
{
var startDate=parseInt($("#autoPlannStartDate").val());
var endDate=parseInt($("#autoPlanEndDate").val());
$("body").addClass("loading");
if (startDate>endDate)
alert("Invalid start date or end date selection");
else
{
if (this.rosterTable.haveInvalidPreferredShift(startDate,endDate))
alert("Invalid shift requirement detected");
else
{
var self=this;
var finalRoster;
var roster,tempAverageSD,lowestAverageSD=100.0;
this.theLowestSDRosters=[];
this.theLowestMissingShiftRosters=[];
for (var i=0;i<100;i++)
{
this._genRoster(startDate,endDate);
}
console.log("Done");
}
}
}
}
我发现,如果我标记了for循环,则加载屏幕正常工作。 如果取消注释for循环,则在控制台中显示“完成”后,将显示加载屏幕。我该如何解决该问题?我试图将_genRoster函数转换为Promise函数,但是它不起作用。
答案 0 :(得分:3)
_genRoster
似乎正在阻塞浏览器,并且直到循环完成之前,都没有提供任何资源来重新渲染/重新绘制。一种可能是在之后运行循环,使浏览器有几毫秒的时间来渲染.loading
:
this.theLowestSDRosters = [];
this.theLowestMissingShiftRosters = [];
setTimeout(() => {
for (var i = 0; i < 100; i++) {
this._genRoster(startDate, endDate);
}
console.log("Done");
}, 50);
在单个requestAnimationFrame
之后调用超时为0的函数可能会更优雅,从而使浏览器有时间进行重新绘制,然后立即运行重循环:
(警告:以下代码会阻塞您的浏览器一段时间)
document.body.style.backgroundColor = 'green';
window.requestAnimationFrame(() => {
console.log('start, setting timeout');
setTimeout(() => {
for (let i = 0; i < 1000000000; i++) {
}
console.log('done');
});
});