我有一个带有for循环的项目,大约需要10分钟才能完成。
这是一个html画布操作效果,它仅供个人使用,所以我不太关心速度。
然而,有一件事情真的很好,如果我可以添加一个进度条,这样我就可以知道程序通过循环到达了多远。
在循环结束之前,问题似乎没有尝试过。
例如,请考虑以下代码:
app.controller('MyController', function($filter) {
var makeItPretty = $filter('makeItPretty');
var myPrettyText = makeItPretty('tHiS iS UgLy!');
});
使用此代码,在完成循环之前,内部html不会写入div。因此它不能用作更新功能。
我也试过var updateDiv = document.getElementById("update"); //Get a div to write progress to
for(i=0;i<10000;i++){
//super crazy code
updateDiv.innerHTML = i;
}
,效果相同。
我发现在循环执行期间显示的唯一javascript功能是“警报”,它会暂停循环执行,并强制您单击一百万次以完成内部循环。所以基本上没有了。
有没有办法显示for循环进度?
答案 0 :(得分:2)
它没有改变的原因是因为没有页面重绘。没有页面重绘的原因是因为JavaScript在任务队列中工作。
由于您的for
循环当前通过使用操作系统100%的可用功率来最大化处理器(实际百分比将根据浏览器和操作系统而变化),不允许其他任务运行直到for循环完成 - 此时所请求的页面重绘将运行(也更新你的图形)。
你应该做的是使用requestAnimationFrame
MDN来完成这项工作而不是一个非常大的for循环。这将允许您为动画,监控以及将来可能提出的任何其他内容提供各种其他挂钩。
答案 1 :(得分:0)
避免同步进行。这会锁定浏览器,不允许任何其他事情发生。没有任何绘制周期可以发生,看起来没什么变化。
尝试将其分解为只执行一步的函数,然后在超时时反复调用它。
var updateDiv = document.getElementById("update");
var i = 0;
var timeout;
function stopProcessing() {
if(timeout) {
clearTimeout(timeout);
}
}
function doStep() {
//super crazy code
updateDiv.innerHTML = i;
i++;
if (i <= 100000) {
timeout = setTimeout(doStep);
}
}
doStep();
<div id="update"></div>
<button onclick="stopProcessing()">Stop</button>
如果您需要此过程尽可能快,则需要setTimeout
。如果要与画布的动画缓冲区同步,请使用requestAnimationFrame
以下代码显示setTimeout
的运行速度比requestAnimationFrame
快得多:
var rafEl = document.getElementById('requestAnimationFrame');
var stEl = document.getElementById('setTimeout');
var rafVal = 0;
var stVal = 0;
function rafFn() {
rafVal++;
rafEl.textContent = rafVal;
if (rafVal < 1000) {
requestAnimationFrame(rafFn);
}
}
function stFn() {
stVal++;
stEl.textContent = stVal;
if (stVal < 1000) {
setTimeout(stFn);
}
}
rafFn();
stFn();
<div>requestAnimationFrame: <span id="requestAnimationFrame"></span></div>
<div>setTimeout: <span id="setTimeout"></span></div>
答案 2 :(得分:0)
要显示您可以使用setInterval()
的进度,请执行以下操作:
var interval = setInterval(function() {
updateDiv.innerHTML = i;
if (i == max)
clearInterval(interval);
i++;
}, 50);
代码:
var updateDiv = document.getElementById("update"); //Get a div to write progress to
var i = 0;
var max = 100;
var interval = setInterval(function() {
updateDiv.innerHTML = i;
if (i == max)
clearInterval(interval);
i++;
}, 50);
&#13;
<div id="update"></div>
&#13;