提问人:danbae 提问时间:1/26/2023 最后编辑:danbae 更新时间:1/26/2023 访问量:47
运行后台脚本时延迟 javascript DOM 更改
Delaying javascript DOM change when running background script
问:
我正在编写一个脚本,该脚本有时涉及在渲染结果之前进行许多耗时的计算,有时只是几个。为了通知用户正在发生延迟,在计算过程中会显示一个“手表”符号。目前为止,一切都好。但是,如果延迟很短,我不希望显示手表,因为符号的重复短暂闪烁可能会令人讨厌。我不能用来延迟手表的显示,因为在顺序计算操作完成之前,该功能无法结束。
在阅读 SO 时,我发现建议使用 Web Worker 来获取计算操作的异步行为。但是,即使将计算委托给 Web Worker,手表的闪烁行为仍然存在。同样,不能用于延迟手表的渲染,因为在延迟结束之前就完成了快速操作。作为最后的手段,我使用延迟方法,这很有效。但使用起来似乎不那么优雅.有没有更方便的方法来实现这一目标?
下面是一个带有脚本和 WebWorker 演示的 html 页面,分别显示了各种方法在长操作和短操作期间的行为,其中第三个在我手中给出了所需的结果。您可以通过注释掉其他内容在它们之间切换。
main.htmlsetTimeout()
setTimeout()
fadeIn()
fadeIn()
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
jQuery(function($){
const worker = new Worker("asyncWorker.js");
$("#shortbtn,#longbtn").click(function(){
$("#done").hide();
/* METHOD 1 */
setTimeout(function(){
$("#wait").show();
},100);
/* METHOD 2 */
//$("#wait").show();
/* METHOD 3 */
//$("#wait").fadeIn(100);
let btnId = $(this).attr("id");
worker.postMessage(btnId);
worker.addEventListener("message",function(message){
$("#wait").hide();
$("#done").show();
});
});
})
</script>
<style>
#wait,#done{display:none;}
#wait{font-size: 4em;}
</style>
</head>
<body>
<button id="shortbtn">Short delay</button>
<button id="longbtn">Long delay</button>
<div id="div">
<span id="wait">⌚</span>
<span id="done">Done!</span>
</div>
</body>
</html>
异步工作者.js
addEventListener("message",function(message){
switch(message.data){
case "shortbtn":
for(let i=0;i<1000;i++){let a = 0;}// simulate quick process
break;
case "longbtn":
for(let i=0;i<3*1e9;i++){let a = 0;} // simulate slow process
break;
}
postMessage("done");
});
答:
0赞
danbae
1/26/2023
#1
正如@A_A所建议的,解决方案是在计算完成时使用并清除超时。也许这很明显,但只要版主不介意,我就会保留这个问题。setTimeout()
来自 main.html:
/* METHOD 4 */
let tmo = setTimeout(function(){
$("#wait").show();
},250);
let btnId = $(this).attr("id");
worker.postMessage(btnId);
worker.addEventListener("message",function(message){
clearTimeout(tmo); // prevents overdue timeout
$("#wait").hide();
$("#done").show();
});
评论
setTimeout