javascript中的setTimeout不提供浏览器';呼吸室';
好吧,我以为我把这整件事都做好了,但我似乎大错特错了 我正在使用excanvas和javascript绘制我家乡的地图,但是绘制过程会阻塞浏览器。现在我不得不迎合IE6,因为我在一个大的组织中,这可能是速度缓慢的很大一部分 所以我想我应该做的是建立一个称为distributedDrawPolys的过程(我可能在这里使用了错误的词,所以不要关注distributed这个词),它基本上从全局数组中弹出多边形,以便一次绘制50个 这是将多边形推送到全局数组并运行setTimeout的方法:javascript中的setTimeout不提供浏览器';呼吸室';,javascript,xml,settimeout,excanvas,census,Javascript,Xml,Settimeout,Excanvas,Census,好吧,我以为我把这整件事都做好了,但我似乎大错特错了 我正在使用excanvas和javascript绘制我家乡的地图,但是绘制过程会阻塞浏览器。现在我不得不迎合IE6,因为我在一个大的组织中,这可能是速度缓慢的很大一部分 所以我想我应该做的是建立一个称为distributedDrawPolys的过程(我可能在这里使用了错误的词,所以不要关注distributed这个词),它基本上从全局数组中弹出多边形,以便一次绘制50个 这是将多边形推送到全局数组并运行setTimeout的方法: for
for (var x = 0; x < polygon.length; x++) {
coordsObject.push(polygon[x]);
fifty++;
if (fifty > 49) {
timeOutID = setTimeout(distributedDrawPolys, 5000);
fifty = 0;
}
}
for(var x=0;x49){
timeOutID=setTimeout(distributedDrawPolys,5000);
五十=0;
}
}
我在这个方法的末尾放了一个警报,它几乎在一秒钟内运行
分布式方法看起来如下:
function distributedDrawPolys()
{
if (coordsObject.length > 0) {
for (x = 0; x < 50; x++) { //Only do 50 polygons
var polygon = coordsObject.pop();
var coordinate = polygon.selectNodes("Coordinates/point");
var zip = polygon.selectNodes("ZipCode");
var rating = polygon.selectNodes("Score");
if (zip[0].text.indexOf("HH") == -1) {
var lastOriginCoord = [];
for (var y = 0; y < coordinate.length; y++) {
var point = coordinate[y];
latitude = shiftLat(point.getAttribute("lat"));
longitude = shiftLong(point.getAttribute("long"));
if (y == 0) {
lastOriginCoord[0] = point.getAttribute("long");
lastOriginCoord[1] = point.getAttribute("lat");
}
if (y == 1) {
beginPoly(longitude, latitude);
}
if (y > 0) {
if (translateLongToX(longitude) > 0 && translateLongToX(longitude) < 800 && translateLatToY(latitude) > 0 && translateLatToY(latitude) < 600) {
drawPolyPoint(longitude, latitude);
}
}
}
y = 0;
if (zip[0].text != targetZipCode) {
if (rating[0] != null) {
if (rating[0].text == "Excellent") {
endPoly("rgb(0,153,0)");
}
else if (rating[0].text == "Good") {
endPoly("rgb(153,204,102)");
}
else if (rating[0].text == "Average") {
endPoly("rgb(255,255,153)");
}
}
else { endPoly("rgb(255,255,255)"); }
}
else {
endPoly("rgb(255,0,0)");
}
}
}
}
}
函数分布式DrawPolys()
{
如果(coordsObject.length>0){
对于(x=0;x<50;x++){//只做50个多边形
var polygon=coordsObject.pop();
变量坐标=多边形。选择节点(“坐标/点”);
var zip=polygon.selectNodes(“ZipCode”);
var评级=多边形。选择节点(“分数”);
if(zip[0].text.indexOf(“HH”)=-1){
var lastOriginCoord=[];
对于(变量y=0;y0){
if(translateLongToX(经度)>0&&translateLongToX(经度)<800&&translateLatToY(纬度)>0&&translateLatToY(纬度)<600){
drawPolyPoint(经度、纬度);
}
}
}
y=0;
if(zip[0].text!=targetZipCode){
如果(额定值[0]!=null){
如果(评分[0]。文本==“优秀”){
endPoly(“rgb(0153,0)”);
}
else if(评级[0]。文本==“良好”){
endPoly(“rgb(153204102)”);
}
else if(评级[0]。文本=“平均值”){
endPoly(“rgb(255255153)”);
}
}
else{endPoly(“rgb(255255)”;}
}
否则{
endPoly(“rgb(255,0,0)”);
}
}
}
}
}
编辑:修正了格式
因此,我认为setTimeout方法将允许站点分组绘制多边形,以便用户能够在页面仍在绘制时与页面交互。我做错了什么?如果循环在一秒钟内运行,则所有
setTimeout
调用都将在大约五秒钟后尝试触发
如果要为浏览器提供中间渲染的喘息空间,请将所有对象推到堆栈上,然后调用具有限制的函数,并在完成这么多对象时让函数调度本身。半伪码:
var theArray = [];
var limit = 50;
function showStuff() {
for (...) {
// push objects on theArray
}
renderArrayInBatches();
}
function renderArrayInBatches() {
var counter;
for (counter = limit; counter > 0; --counter) {
// pop an object and render it
}
if (theArray.length > 0) {
setTimeout(renderArrayInBatches, 10);
}
}
这将一次性构建阵列,然后触发第一批渲染(最多限制
)。在第一批处理结束时,如果还有更多渲染要做,它会将渲染时间安排在大约10毫秒后。事实上,如果浏览器仍然忙于其他事情,它很可能会在10毫秒后发生,甚至更晚。(关于10毫秒:大多数浏览器不会在10毫秒之后安排某些内容。)(EditAndy E非常正确地指出,您可以将与需要渲染的内容相关的逻辑直接折叠到渲染函数中,而不是首先构建阵列,然后对其进行处理。除了阵列部分、链接方式和“呼吸空间”外,上述内容没有太大变化保持不变。)
由于不知道您正在使用的excanvas工具,您可能会发现需要调整超时时间,但我倾向于对此表示怀疑——这基本上是一种“屈服”操作,它让浏览器做一些事情并返回给您
请注意,上面的psuedo代码示例使用的似乎是globals。我不建议实际使用globals。您甚至可能希望这样做:
function showStuff() {
var theArray = [];
var limit = 50;
for (...) {
// push objects on theArray
}
renderArrayInBatches();
function renderArrayInBatches() {
var counter;
for (counter = limit; counter > 0; --counter) {
// pop an object and render it
}
if (theArray.length > 0) {
setTimeout(renderArrayInBatches, 10);
}
}
}
…但我不想通过引入闭包使主要答案复杂化(虽然从技术上讲,两个代码块都涉及闭包)。将代码更改为
for (var x = 0; x < polygon.length; x++) {
coordsObject.push(polygon[x]);
}
distributedDrawPolys();
function distributedDrawPolys()
{
if (coordsObject.length > 0) {
for (x = 0; x < 50; x++) {
...
}
setTimeout("distributedDrawPolys()", 5000); //render next 50 polys in 5 sec
}
}
for(var x=0;x0){
对于(x=0;x<50;x++){
...
}
setTimeout(“distributedDrawPolys()”,5000);//在5秒内渲染下一个50个多边形
}
}
这不符合预期。当您的第一个函数开始执行时,您的全局数组已经包含50个元素。您只需对相同的数据5进行操作即可
var coordObj = [...]; //50 or whatever elements
(function() {
if (coordObj.length === 0) return; //Guardian
var obj = coordObj.pop(); //or .shift(), based on the order desired.
doStuffWithCoordObj(obj);
setTimeout(arguments.callee,0); //call this anonymous function after a timeout
})();
var batchsize = 50;
function drawPolys(start) {
for (var x = start; x < polygon.length; x++) {
drawOnePolygon(polygon[x]);
if (start + batchsize <= x) {
// quit this invocation, and schedule the next
setTimeout(function(){drawPolys(x+1);}, 400);
return; // important
}
}
}
function drawOnePolygon(p) {
var coordinate = polygon.selectNodes("Coordinates/point");
//...and so on, continuing from your code above.
}
drawPolys(0);