JavaScript:提高FOR循环的性能以阻止浏览器锁定?

JavaScript:提高FOR循环的性能以阻止浏览器锁定?,javascript,Javascript,我有一个对象数组,我一次循环一个对象,检查数组中的每个对象是否符合某些条件,如果该对象符合这些条件,我将该对象的一个属性复制到一个数组中(该属性还包含另一个对象) 现在由于某种原因,如果这个对象数组的大小很大(5000+),那么这个操作会变得非常昂贵,浏览器只会锁定一两秒钟(甚至更多) 我无法提供更多关于代码功能的信息,但我想知道,在这个循环中,让浏览器休息的最佳方式是什么,比如说每500次迭代,这样它就不会锁定,然后继续等等 谢谢将循环的结构更改为: var index = 0; functi

我有一个对象数组,我一次循环一个对象,检查数组中的每个对象是否符合某些条件,如果该对象符合这些条件,我将该对象的一个属性复制到一个数组中(该属性还包含另一个对象)

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

我无法提供更多关于代码功能的信息,但我想知道,在这个循环中,让浏览器休息的最佳方式是什么,比如说每500次迭代,这样它就不会锁定,然后继续等等


谢谢

将循环的结构更改为:

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
调用


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

不确定。。。但是,将代码放入函数中,然后中断并调用该函数(比如说每个xMs)怎么样

例如

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();
var maxStatement=1000,currentIndex=0,timeoutVar=''
var sLimit=features.length
函数multiStepLoop(){
对于(var i=currentIndex;i=a){maxStatement=a}

如果(a如果你做了一些有点突发和有点递归的事情怎么办:

主要功能 发生的情况是,给定的
索引
突发
间隔量(即500)传递,当
for
循环以给定的
突发
迭代次数结束时,它会以相同的突发数调用自身。当特征数组结束时,函数结束

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);
    }
};
诚然,它与您将要使用的
onScreen()
测试不同,但无论哪种方式,它的计算结果都是
布尔值。我认为,如果您将此概念应用到代码中,您可能会获得惊人的结果

中的所有内容都被称为:

randomFeatures(features, 5000);
console.log(features.length);
transferFeatures(0,500);
console.log(dataArray.length);
负载测试 我模拟了
5000000
(500万)个随机对象被推到
功能上,其中
突发
1000
,脚本大约在3.29秒内完成。

将数组拆分为1000个对象的块,并使用
setTimeout()
来处理下一个区块。可能的副本会很有趣,看看屏幕上的
后面隐藏着什么。也许你可以通过优化此功能来进一步提高性能。为什么你不能深入了解更多信息?网络工作者只对有限数量的浏览器可用…我在开玩笑吧…他们在IE9和以下版本中不工作w、 差不多it@Christopher-对webworkers的可用性进行检查,并在可用的情况下使用它们,这将加快速度,使其在除IE之外的所有浏览器中不再明显。嗨,JoDev,这是否意味着我们将在每次迭代时设置超时?是的,setTimeOut允许您使用睡眠时间进行迭代…该函数将被调用每次设置一次超时是一个好主意吗?或者每次设置一次超时(比如说500次)不是更有效吗?如果我没有弄错的话,即使您调用了setTimeOut('myfunc',500);最后,while循环仍将继续,然后在500毫秒后它将再次调用该方法。是的,请将超时代码移到while中…我会将其更改为appassing
DoLoop()
像这样的字符串是
eval
的一种形式,速度非常慢。这只会有助于减慢过程,而不是优化过程。
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);
    }
};
//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"
            }
        });
    }
};
randomFeatures(features, 5000);
console.log(features.length);
transferFeatures(0,500);
console.log(dataArray.length);