Javascript:如何在onClick完成之前更新页面?
我有一个用于解析20MB XML文件的函数。它工作得很好,但我想在这一分钟左右给出一些进展指示 但是,这不起作用: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
<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;isetTimeout
正是您处理此问题的方式,但您必须正确构造解析函数。您最不想做的事情是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节点要解析,这是将进度分解为前序或其他用户通知的最佳方式,但我如何在不循环/迭代的情况下处理它们他们是谁?