如何报告 JavaScript 函数的进度?
我有一个 JavaScript 函数,它很长并且执行许多任务,我想通过使用消息更新 SPAN 元素的内容来向用户报告进度。我尝试在整个函数代码中添加 document.getElementById('spnProgress').innerText = ... 语句。
然而,当该函数正在执行时,UI 不会更新,因此您只能看到写入 SPAN 的最后一条消息,这并不是很有帮助。
我当前的解决方案是将任务分解为多个函数,在每个函数结束时设置 SPAN 消息,然后通过 window.setTimeout 调用以非常短的延迟(例如 10 毫秒)“触发”下一个函数。这将产生控制权,并允许浏览器在开始下一步之前使用更新的消息重新绘制 SPAN。
然而我发现这非常混乱并且很难遵循代码,我想一定有更好的方法。有人有什么建议吗?有没有什么方法可以强制 SPAN 重新绘制而不必离开函数的上下文?
谢谢
I have a JavaScript function which is quite long and performs a number of tasks, I would like to report progress to the user by updating the contents of a SPAN element with a message as I go. I tried adding document.getElementById('spnProgress').innerText = ... statements throughout the function code.
However, whilst the function is executing the UI will not update and so you only ever see the last message written to the SPAN which is not very helpful.
My current solution is to break the task up into a number of functions, at the end of each I set the SPAN message and then "trigger" the next one with a window.setTimeout call with a very short delay (say 10ms). This yields control and allows the browser to repaint the SPAN with the updated message before starting the next step.
However I find this very messy and difficult to follow the code, I'm thinking there must be a better way. Does anyone have any suggestions? Is there any way to force the SPAN to repaint without having to leave the context of the function?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(6)
您需要注意,在某些浏览器中,如果您有长时间运行的脚本,您将收到脚本超时消息。所以实际上最好使用计时器来分割它。
话虽如此,如果您正在寻找一种真正结构化的方法来执行此操作,那么您可以查看我为拼写检查项目编写的后台任务库。它允许您对计时器上的数据数组实施映射/归约。
如果你的函数的工作是在循环中执行的,这样的事情可能会起作用。
它检查已经过去的时间量,如果已经过去 1/2 秒,则更新进度条。 (该示例未经测试。因此您可能需要稍微尝试一下。)
var start;
function longRunning(lastState){
start = (new Date);
for(var i = lastState; i < 1e6 /*= 1000000 iterations */; ++i){
if((new Date)-start<500){
// do your stuff;
}
else{
// call a function to update the progress bar
updateProgressBar();
// continue the loop...
setTimeout(function(){longRunning(i);},13);
break;
}
}
}
longRunning(0);
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
您这样做的方式是正确的方式(目前,随着标准的出现和采用,这可能会改变[参见 Andrew Aylett 的 answer],但暂时还没有)。您必须像这样屈服才能允许浏览器进行 UI 更新。我发现我越这样想,事情就越干净,但我最初的几次尝试确实相当“混乱”。希望您在习惯后发现同样的事情。
The way you're doing it is the right way (at the moment, this may change as standards emerge and are adopted [see Andrew Aylett's answer], but not for a while yet). You have to yield like that to allow the browser to do its UI updates. I've found that the more I think like this, the cleaner things get, but my first few stabs at doing it were indeed quite "messy." Hopefully you find the same thing as you get used to it.