我编写的 javascript 需要 20-30 秒才能处理,我想通过更新网页上的进度条来显示进度。
我已使用 setTimeout 尝试重新绘制网页。
我的代码是这样的:
function lengthyFun(...){
for(...){
var progress = ...
document.getElementById('progress-bar').setAttribute('style',"width:{0}%".format(Math.ceil(progress)));
var x = ...
// Processing
setTimeout(function(x) { return function() { ... }; }(x), 0);
}
}
它不起作用,我知道它为什么不起作用,但我不知道如何重构我的代码以使其起作用。
最佳答案
您可能知道,这里的问题是您的主进程(花费大量时间的进程)正在阻止任何渲染。那是因为 JavaScript(大部分)是单线程的。
在我看来,您有两种解决方案可以做到这一点。 第一个是将您的主要流程削减为不同的部分,并在每个部分之间进行渲染。 IE。你可以有类似的东西(使用 promise ):
var processParts = [/* array of func returning promises */];
function start(){
// call the first process parts
var firstPartPromise = (processParts.shift())();
// chain it with all the other process parts interspersed by updateDisplay
return processParts.reduce(function(prev, current){
return val.then(current).then(updateDisplay);
}, firstPartPromise);
}
您可能需要一个 polyfill 来实现 promise (one here)。如果您使用 jQuery,它们有一个(糟糕的非标准)实现。
第二种解决方案可以是使用 webworkers它允许您在 JavaScript 中创建线程。它适用于所有现代浏览器。 这可能是您情况下的最佳解决方案。 我从未使用过它们,但您应该能够执行以下操作:
var process = new Worker("process.js");
worker.onmessage(function(event){
updateProgress(event.data.progress)
});
在 process.js
中:
postMessage({progress: 0.1});
// stuff
postMessage({progress: 0.4});
// stuff
postMessage({progress: 0.7});
//etc
关于javascript - 在 javascript 循环运行时更新网页以显示进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32299326/