Javascript:如何在onClick完成之前更新页面?

Javascript:如何在onClick完成之前更新页面?,javascript,settimeout,Javascript,Settimeout,我有一个用于解析20MB XML文件的函数。它工作得很好,但我想在这一分钟左右给出一些进展指示 但是,这不起作用: <head> <script type="text/javascript"> function pauseJS(timeInMilliS) { var date = new Date(); var curDate = null; do { curDate = new Date(); } while(curDate-date

我有一个用于解析20MB XML文件的函数。它工作得很好,但我想在这一分钟左右给出一些进展指示

但是,这不起作用:

<head>

<script type="text/javascript">

function pauseJS(timeInMilliS) {
    var date = new Date();
    var curDate = null;
    do { curDate = new Date(); }
    while(curDate-date < timeInMilliS);
}

function process() {
    for (var i = 0; i<=10; i++) {
        document.images["bar"].width += 5;
        document.images["bar"].height = 5;      
        pauseJS(500);
    }
}
</script>

</head>

<body>
    <input type="button" value="Go" onClick="process()"> 
    <img src="black.gif" name="bar" width=1 height=5 />
</body>

函数pauseJS(时间单位:毫秒){
变量日期=新日期();
var curDate=null;
do{curDate=new Date();}
while(curDate-date对于(var i=0;i
setTimeout
正是您处理此问题的方式,但您必须正确构造解析函数。您最不想做的事情是
pauseJS
中显示的忙碌等待。这不会暂停JavaScript,这会使JavaScript疯狂运行,直到达到时间或浏览器取消脚本过度消费。:-)

为了让浏览器有时间更新页面显示,您必须让JavaScript线程返回到浏览器。例如,这将不起作用:

var TOTAL = 10000000;
var BATCH = 10000;

function doSomething() {
    for (n = 0; n < TOTAL; ++n) {
        if ((n % BATCH) == 0) {
            // ...change progress indicator...
        }

        // ...do processing...
    }
}
var总计=10000000;
var批次=10000;
函数doSomething(){
对于(n=0;n
…因为它永远不会让步。另一方面,这是有效的:

var TOTAL = 10000000;
var BATCH = 10000;

function doSomething() {
    var n = 0;

    work();

    function work() {
        var maxn = Math.min(n + BATCH, TOTAL);

        for ( ; n < maxn; ++n) {
            // ...do processing...
        }

        // ...update progress indicator...

        if (n < TOTAL) {
            setTimeout(work, 0);
        }
    }
}
var总计=10000000;
var批次=10000;
函数doSomething(){
var n=0;
工作();
职能工作(){
var maxn=数学最小值(n+批次,总计);
对于(;n

正如您所看到的,这里我们将工作分解为离散的批,并定期停止、安排下一批工作,并将控制权返回到浏览器。这给了它更新页面的时间,之后它将调用我们(确切地说不是在0毫秒之后,而是在下一次更新时,这通常是更新自身加上5-10毫秒所需的时间)。

Javascript只有一个线程,这意味着您无法一次完成多个任务


您必须中断XML处理函数,以便它执行大量工作、更新进度条等等。

使用
setInterval()会有区别吗
?我猜只是语义上的。@Jared:我强烈建议在这种情况下不要使用
setInterval
setInterval
会定期触发,但当它调用的函数执行时间比间隔时间长时会变得有点混乱。有些浏览器会跳过下一个预定调用,因此如果您的间隔是(比如)30毫秒时,您会在+30毫秒、+60毫秒和+90毫秒时被呼叫,但由于某些原因,+120毫秒的呼叫需要40毫秒才能完成,超过了间隔时间,您将完全错过+150毫秒的呼叫,必须等待+180毫秒。其他实现可能会让您离得更近。在这种情况下,重新调度的
setTimeout
更好。谢谢,TJ,Evan不是这样关于单线程的e有助于理解它为什么会这样。那么,问题是,如何让脚本在没有循环的情况下完成大量工作??在我的例子中,例如,我有1000个XML节点要解析,这是将进度分解为前序或其他用户通知的最佳方式,但我如何在不循环/迭代的情况下处理它们他们是谁?