在进行漫长的JavaScript计算时如何强制浏览器更新UI?

22

我有一个网页应用程序中的一个地方,我正在使用 在浏览器中 的 JavaScript 进行大量计算。这些计算可能需要少于一秒钟到大约一分钟的时间才能运行,并且我希望在此步骤中显示进度对话框,但是对话框要等到计算完成后才会显示。起初,我只是尝试显示一个 jQuery 对话框:

HTML:

<input type="button" id="startwork" value="Start working">

<div id="dialog" title="My dialog">
    This should show up immediately on clicking the button.
</div>

脚本:

$(function() {

    $("#startwork").click(function () {
        $("#dialog").dialog("open");
        // Do some lengthy calculations
        for (var i=0; i<1000000000; i++) {
            var foo = Math.random();   
        }
        $("#dialog").dialog("close");
        alert("done");
    });

    $("#dialog").dialog({ autoOpen: false });

});

我应该怎么做才能在计算开始前和定义好的间隔期间强制更新UI呢?

2个回答

28

将耗时的计算放在一个setTimeout中:

setTimeout(function() {
// some length calculations
}, 0);

setTimeout后面不应该再有其他脚本。

$(function() {

    $("#startwork").click(function () {
        $("#dialog").dialog("open");
        setTimeout(function() {
            // some length calculations
            for (var i=0; i<1000000000; i++) {
                var foo = Math.random();   
            }
            $("#dialog").dialog("close");
            alert("done");
        }, 0);
    });

    $("#dialog").dialog({ autoOpen: false });

});

谢谢。我建立了一个工作任务队列,并使用setTimeout按顺序启动队列中的每个项目。效果很好。 - Chris Farmer
4
@ExceptionSlayer实现了任务队列的超时功能。如果在超时之前有任何任务被加入到队列中,则通常会先执行这些任务,包括绘制用户界面。这篇文章对JavaScript定时器的工作原理进行了详细介绍:http://ejohn.org/blog/how-javascript-timers-work/。 - dewd

2
如果您想在进行计算时显示一个对话框,可以使用 setTimeout 在显示对话框后调用长时间计算。如果您想显示进度条,则必须在处理过程的方便点使用一系列 setTimeout 调用。当一个调用结束时,它会更新进度条并调用下一个调用,直到完成全部操作。
但是,在任何特定脚本运行时,用户界面将被阻塞。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接