(请参阅底部的更新)
我已经查看过几十个问题而无法完成这项工作。
鉴于下面的代码,如何在每次迭代后强制它更新我的简单进度指示器($(“#log”))?
编辑:我认为这个JSFiddle举例说明了我的问题:http://jsfiddle.net/kPRky/
这是HTML:
<div id="test"></div>
<div id="log"></div>
这就是函数的调用方式:
$("#test").html(createLevelMap());
这就是功能
function createLevelMap() {
var height = 300;
var width = 1000;
var totalpixels = height * width; //used for calculating loading percentages;
var currentpixel = 0; //used for calculating loading percentages;
var x = 0;
var y = 0;
//lots of other variables
for (x = 0; x < width; x += 1) {
for (y = 0; y < height; y += 1) {
//lots of calculations with lots of variables
currentpixel += 1;
$("#log").html((currentpixel / totalpixels) * 100 + "%");
}
}
return ('done'); //actually returns a very long base64 encoded string
}
更新
我简化了它,以便我有一个单独的函数来渲染每一列,而不是整个网格。但是,使用setTimeout仍然不会导致正确显示进度。
for (x = 0; x < width; x += 1) {
$("#log").html(((x + 1) / width) * 100 + "%<br>(sliver " + (x + 1) + "/" + width + ")");
setTimeout(createSliver(x), 100);
}
^^这导致我期望的输出,但没有百分比更新。我将其更改为setTimeout(function(){createSliver(x)},100);按照评论中的建议然后我甚至没有得到我的输出(也仍然没有增加百分比)。
答案 0 :(得分:0)
这个怎么样?
var height = 300;
var width = 1000;
var totalpixels = height * width; //used for calculating loading percentages;
var currentpixel = 0; //used for calculating loading percentages;
incrementAndUpdate(currentpixel, totalpixels);
function incrementAndUpdate(currentValue, totalPixels) {
$("#log").html((currentValue / totalPixels) * 100 + "%");
if (currentValue < totalPixels) {
setTimeout(function () { incrementAndUpdate(currentValue + 1, totalPixels); }, 1);
}
}
鉴于此速度很慢,我建议你可以用较少的频率调用它,并在每次尝试setTimeout / html更新调用时做更多的工作单元。也许创建一个要做的工作队列,并在你的incrementAndUpdate
函数中,选择直接调用函数,或者通过setTimeout。
像这样......
function incrementAndUpdate(currentValue, totalPixels) {
$("#log").html((currentValue / totalPixels) * 100 + "%");
// do a bit of work.
if (currentValue < totalPixels) {
var workFunction = function () { incrementAndUpdate(currentValue + 1, totalPixels); }
if (currentValue % 100 == 0)
setTimeout(workFunction, 1);
else
workFunction();
}
}
这可以完成相同的工作,但是通过较少的setTimeout
次调用可以更快地完成工作。您可以调整调用setTimeout的频率,以便尽可能优化用户体验。
以下是您的小提琴的更新:http://jsfiddle.net/kPRky/1/
答案 1 :(得分:0)
最好的解决方案是使用Web Workers。这使您可以在完全不同的线程中运行处理UI更新。如果您需要支持没有Web worker的浏览器,则需要使用setTimeout为GUI更新提供运行的机会。
如果使用超时方法,您可以通过设置最大时间来获得最佳体验,然后在断开循环并调用setTimeout之前让它运行。这将让GUI重新绘制。
这里有一个例子:http://jsfiddle.net/kPRky/6/
您可以通过在somethingSlow方法中添加/删除零来加快/减慢速度。
答案 2 :(得分:0)
所以我通过从内部调用setTimeout()函数来获得更新的进度。这是我失踪的关键。
现在是基本格式:
function nextRow() {
x += 1;
setTimeout(function () { createSliver() }, 100);
if (x < width) { setTimeout(function () { nextRow() }, 100); }
}
function createSliver() {
//do stuff here
currentpixel += 1;
$("#log").html(((currentpixel) / totalpixels) * 100 + "%<br>(pixel " + (currentpixel) + "/" + totalpixels + ")");
y += 1;
if (y < height) {
setTimeout(function () { createSliver() }, 100);
} else {
y = 0;
}
function mainFunction() {
setTimeout(function () { nextRow() }, 100);
return (data);
}
但是现在我的“数据”没有正常回归。我假设因为现在一切都在异步运行......大便。