1

我有一个对象数组,我一次循环遍历这个数组一个对象,并进行几次检查以查看该数组中的每个对象是否符合某些标准,如果该对象符合该标准,然后我复制该对象的一个​​属性放入一个数组(该属性还包含另一个对象)。

for(var v = 0; features.length > v; v++){
   var feature = features[v];
    //If the feature is on the map then we want to add it
    if(feature.onScreen()){     
        dataArray.push(feature.attributes); 
    }
}

现在由于某种原因,如果这个对象数组的大小很大(5000+),这个操作会变得非常昂贵,并且浏览器只会锁定一两秒(有时更多)。

我无法详细了解代码的作用,但我想知道给定这个循环,让浏览器休息的最好方法是每 500 次迭代,所以它不会锁定然后继续等等

谢谢

4

4 回答 4

0

将循环的结构更改为:

var index = 0;
function myfunc() {
   while(features.length > index){
       var feature = features[v];
       //If the feature is on the map then we want to add it
       if(feature.onScreen()){     
          dataArray.push(feature.attributes);

       }
       index++;
       //You can do this
       var waitingTime = 0;
       If (index% 500=0) waitingTime=100; //or 10, 20...
       //Or just with a short interval
       var waitingTime = 10;
       setTimeOut('myfunc', waitingTime);
   }
}

或者带一个参数:[我更喜欢这个]

function myfunc(index) {
    if(!index) {
       index=0;
    }

    while(features.length > index){
       var feature = features[v];
       //If the feature is on the map then we want to add it
       if(feature.onScreen()){     
          dataArray.push(feature.attributes);
       }
        //You can do this
       var waitingTime = 0;
       If (index% 500=0) waitingTime=100; //or 10, 20...
       //Or just with a short interval
       var waitingTime = 10;
       setTimeOut('myfunc', waitingTime);
   }
}

[编辑]
更改setTimeOut呼叫...

在你的代码中,当你调用函数时,不要给参数,初始化索引!

于 2013-03-27T10:53:10.947 回答
0

不确定...但是将该代码放入一个函数中,然后分解并调用该函数(比如每个 xMs)怎么样?

例如,

var LastPos = 0;

function DoLoop()
{


    for(var v = LastPos; features.length > v; v++){
                var feature = features[v];
                //If the feature is on the map then we want to add it
                if(feature.onScreen()){     
                    dataArray.push(feature.attributes);

                }

               if(v > 500)
               {
                   LastPos = v;
                   break;
               }
    }
    setTimeout('DoLoop()', 10);
}
于 2013-03-27T10:54:34.597 回答
0

setTimeOut() 可以解决这个问题。

var maxStatement = 1000, currentIndex=0, timeoutVar = ''
var sLimit = features.length

function multiStepLoop(){
    for (var i=currentIndex; i<currentIndex+maxStatement; i++){
        //---DO YOUR STUFFS HERE
    }

    var a = sLimit-i;
    currentIndex += maxStatement;
    if (maxStatement >= a){ maxStatement=a }
    if (a<=0){
        callBackFunction() //-- function to call when your peocess finish.
    }else{
        timeoutVar = setTimeout('multiStepLoop()',1)
    }
}
multiStepLoop();

缺点是你需要把这个过程完成后你想做的所有事情都覆盖到一个函数中,然后像 callBack_Function 一样运行它。

注意:只需将 setTimeout 的时间设置为 1 毫秒,浏览器不会显示等待光标。

于 2013-03-27T10:58:56.370 回答
0

如果你用一点点突发和一点递归做了什么:

小提琴代码

主功能

发生的情况是一个给定的间隔(即 500 个)通过,在以给定的迭代次数结束index循环时,它会以相同的突发数重新调用自己。当特征数组的末尾完成时,函数结束。burstforburst

var transferFeatures = function (index, burst) {
    for (var z = 0; z <= burst; z++) {
        if (index === features.length) {
            return;
        }

        var feature = features[index];

        if (feature.onScreen) {
            dataArray.push(feature.attributes);
        }
        index++;
    }
    if (index !== features.length) {
        transferFeatures(index, burst);
    }
};

测试

为了模拟负载,我使用各种键值对(最重要的是您的attributes内部对象)创建了一个对象数组:

//To simulate a random boolean
var randomBoolean = function () {
    return Math.random() <= 0.5;
};

//A random integer
var getRand = function () {
    return (Math.floor(Math.random() * 10).toString());
};

// Create a bunch of dummy objects
var randomFeatures = function (arr, i) {
    for (var p = 0; p < i; p++) {
        arr.push({
            onScreen: randomBoolean(),
            attributes: {
                width: getRand(),
                height: getRand(),
                someAtt: "I'm just an attribute",
                coolKidsRideBikes: true,
                foo: "bar",
                bar: "baz"
            }
        });
    }
};

当然,这与onScreen()您将使用的测试不同,但无论哪种方式,它都会计算出一个boolean值。我认为如果你在你的代码中应用这个概念,你可能会得到惊人的结果。

我在顶部链接的小提琴中的所有内容都被称为:

randomFeatures(features, 5000);
console.log(features.length);
transferFeatures(0,500);
console.log(dataArray.length);

负载测试

我模拟了(500 万)个随机对象被a of5000000推送到,脚本在大约 3.29 秒内完成。 featuresburst1000模拟负载

于 2013-03-27T13:52:46.327 回答