好吧,我认为我有这整个事情的setTimeout完美,但我似乎是可怕的错误的。

我使用excanvas和JavaScript来绘制地图我的家乡,然而绘图程序扼流圈浏览器。现在,我不得不迎合IE6,因为我在一个大的组织,这可能是缓慢的很大一部分是。

所以我想我会做的是建立一个过程调用distributedDrawPolys(我可能用错了词出现,所以不要集中分布的字)基本上弹出多边形掀起了全局数组,以便同时吸引他们的50。

这是推动到全局阵列的多边形并运行的setTimeout的方法:

 for (var x = 0; x < polygon.length; x++) {
      coordsObject.push(polygon[x]);
      fifty++;
      if (fifty > 49) {
           timeOutID = setTimeout(distributedDrawPolys, 5000);
           fifty = 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)");
                     }
                }
           }
      }
 }

编辑:固定格式

所以我认为setTimeout的方法将允许网站绘制多边形的组,这样用户就可以与网页互动,而它仍然绘制。我在做什么错在这里?

有帮助吗?

解决方案

的代码更改

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
    }
}

其他提示

如果你的循环是在第二下运行,所有的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);
    }
}

这构建阵列的所有一气呵成,然后触发第一批处理渲染的(高达limit)。在第一批的结束,如果有更多的渲染做的,它的时间表它发生后10ms左右。事实上,它会发生任何的越早的超过10ms后,很可能晚于,如果浏览器仍忙于其他事情。 (重新10ms的:大多数浏览器将不会从现在安排的东西迟早大于10ms)(修改安迪Ë指出,非常正确,那你不妨折叠有关需要执行何种逻辑渲染到渲染功能,而不是直接首先构建阵列,则处理它。不改变上述多除了阵列部分,你怎么办链接和“呼吸室”保持相同。)

不知道的东西excanvas你使用,你会发现你需要调整超时时间,但我倾向于怀疑它 - 它基本上是一个“产量”操作,它可以让浏览器做一些事情,然后回来你。

请注意,伪代码示例以上正在使用什么似乎是全局变量。我不会真的建议使用全局变量。你甚至可能要做到这一点,而不是:

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);
        }
    }
}

...但我不喜欢通过引入封闭主要答复复杂化(尽管技术上对代码块涉及闭包)。

没有,你想要的东西不同。

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
        }
    }
}

然后drawOnePolygon必须是这样的:

function drawOnePolygon(p) {
    var coordinate = polygon.selectNodes("Coordinates/point");
    //...and so on, continuing from your code above.
}

与启动它:

drawPolys(0); 

如果你把它每五秒一次,每一次它的工作的1秒时,浏览器将被堵塞的交互的20%的时间。

您可以尝试砍了你的大功能和块运行,使体验更加流畅。

如预期这不起作用。通过你的第一个函数开始执行的时候,你的全局数组中已经包含50个元素。你只是最终在同一数据进行操作50次。

你可以做的是连锁您的setTimeout让下一个功能前面的方法后执行。

下面是一个简单的实现:

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
})();
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top