我遇到的问题是浏览器在应有的情况下并不总是显示“忙”指示器。
下面的代码是TypeScript,但是当然只是JavaScript。这使用kendo,但其他浏览器调用也不起作用。我试过只显示一个繁忙的gif,一个jQuery繁忙的插件,甚至只是向html添加一些文本。
private demo() {
let that = this;
this.slowOperation(function () {
that.cpuIntensiveCode();
}, 20); // < 20 fails to show busy; >= 20 works, but > 50 is better
}
private slowOperation(fun: any, ms: number) {
kendo.ui.progress($(".spinner"), true);
setTimeout(() => this.callback(fun), ms);
}
private callback(fun: any) {
fun();
kendo.ui.progress($(".spinner"), false);
}
如果将ms设置为0,则即使应显示忙碌指示符,也不会显示。这是某种浏览器(Chrome / Firefox)错误吗? “ slowOperation”在当前线程上返回,因此浏览器有机会在调用“ callback”之前更新显示,但是由于某些原因它没有这样做。
我如何显示忙碌指示器,而又不必强制执行一小段时间不执行任何操作?这种延迟是显而易见的。实际上,“ cpuIntensiveCode”中有很多可变性(我的UI有大量的用户选择和组合),它可能很慢,也可能很快,所以我不想添加20ms。知道需要多长时间将是一堆我也不想要的代码。只希望浏览器执行它被告知要做的事情。
因为只有一个线程,所以渲染
kendo.ui.progress($(".spinner"), true);
被阻止,从理论上讲,该方法可能/可能会进行回调,这将确保在渲染完成后进行后续计算。
基本上,您不能期望渲染成为同步脚本执行的一部分。当然,您可以使用requestAnimationFrame
来制作一些东西,但是我认为应该更优选使用渲染方法或Web Worker进行回调。
您所说的20毫秒只是确保进度微调器的呈现在计算开始之前完成。
我想出了同样的工作jsfiddle,它显示了您在说什么,以及Web Worker的出色解决方案,它将在单独的线程上执行代码。