对于大数据,循环执行速度慢

for loop execute slow for large data

本文关键字:执行 速度慢 循环 于大 数据      更新时间:2023-09-26

我有一个 for 循环,执行大量数据需要很长时间:

for (var itm = 0; itm < itmCount; itm++) {
    var curObj = $('[aria-describedby=' + gridName + '_' + columnNames[itm].name + ']');
    var thisCell = $('#' + gridName + '_' + columnNames[itm].name + ' div');
    $('#widthTest').html(thisCell.text()).css({
    'font-family': thisCell.css('font-family'),
    'font-size': thisCell.css('font-size'),
    'font-weight': thisCell.css('font-weight')
    });
    var maxWidth = Width = $('#widthTest').elementRealWidth() + 17;
    var itm2Count = curObj.length;
            // Loop through Rows
            for (var itm2 = 0; itm2 < itm2Count; itm2++) {
            var thisCell = $(curObj[itm2]);
            $('#widthTest').html(thisCell.html()).css({
            'font-family': thisCell.css('font-family'),
            'font-size': thisCell.css('font-size'),
            'font-weight': thisCell.css('font-weight')
            });
            thisWidth = $('#widthTest').elementRealWidth();
            if (thisWidth > maxWidth) {maxWidth = thisWidth+10;}
            }
    $('#' + gridName + ' .jqgfirstrow td:eq(' + itm + '), #' + gridName + '_' + columnNames[itm].name).width(maxWidth).css('min-width', maxWidth+17);
    $('#' + gridName + ' .jqgfirstrow td:eq(' + 0 + '), #' + gridName + '_' + columnNames[0].name).width('30').css('min-width', '30px');

我从火狐得到这个问题:

此页上的脚本可能正忙,或者可能已停止响应。现在可以停止脚本,在调试器中打开脚本,或让脚本继续。

Chrome 会杀死该页面。知道吗?

更新:

这是我做块后的代码:

var itmCount = columnNames.length;
    var numOfElements = itmCount;
    var elementsPerChunk = 50;
    var numOfChunks = numOfElements / elementsPerChunk; //divide it into chunks
    for (var x = 0; x < numOfChunks; x++) {
        setTimeout(function() {
        for (var y = 0; y < elementsPerChunk; y++) {

                var curObj = $('[aria-describedby=' + gridName + '_' + columnNames[elementsPerChunk].name + ']');
                var thisCell = $('#' + gridName + '_' + columnNames[elementsPerChunk].name + ' div');
                $('#widthTest').html(thisCell.text()).css({
                'font-family': thisCell.css('font-family'),
                'font-size': thisCell.css('font-size'),
                'font-weight': thisCell.css('font-weight')
                });
                var maxWidth = Width = $('#widthTest').elementRealWidth() + 17;
                var itm2Count = curObj.length;
                        // Loop through Rows
                        for (var itm2 = 0; itm2 < itm2Count; itm2++) {
                        var thisCell = $(curObj[itm2]);
                        $('#widthTest').html(thisCell.html()).css({
                        'font-family': thisCell.css('font-family'),
                        'font-size': thisCell.css('font-size'),
                        'font-weight': thisCell.css('font-weight')
                        });
                        thisWidth = $('#widthTest').elementRealWidth();
                        if (thisWidth > maxWidth) {maxWidth = thisWidth+10;}
                        }
                $('#' + gridName + ' .jqgfirstrow td:eq(' + elementsPerChunk + '), #' + gridName + '_' + columnNames[elementsPerChunk].name).width(maxWidth).css('min-width', maxWidth+17);
                $('#' + gridName + ' .jqgfirstrow td:eq(' + 0 + '), #' + gridName + '_' + columnNames[0].name).width('30').css('min-width', '30px');
                //grid.setRowData ( iids[itm], false, {height: 30} );
                }
        }, 0);
        }

请记住,JavaScript 完全是浏览器方面的。每个浏览器在认为您的代码超时时都会做出不同的响应。此外,您无法绕过这些错误。一个很好的例子是"阻止此网站再显示弹出窗口"的chromes选项。添加这些功能是为了方便最终用户,通常会修复安全漏洞或通知用户网站只是需要一段时间(大多数用户不喜欢(

一个想法是找到一种方法来拆分您处理的数据量。 正如您所说,问题似乎出在大量数据上。有没有办法将数据拆分为"页面"并一次处理 50 个项目?

如果您可以在更新时创建停止点,那也将起作用。浏览器在JavaScript运行时锁定,这是问题的重要组成部分。

最后,考虑在服务器端处理数据并使用 Ajax 发送/接收数据。这将允许浏览器/用户在其他地方处理代码时工作,并且只停止接收新数据。

编辑:

要解决您的意见:

使用数学,您可以使用嵌套的 for 循环将处理负载拆分为 50 个块:

var numOfElements = /*how ever you count the records*/;
var elementsPerChunk = 50;
var numOfChunks = numOfElements / elementsPerChunk; //divide it into chunks
for (x = 0; x < numOfChunks; x++) {
    //Set Time out
    for (y = 0; y < elementsPerChunk; y++) {
        //Rest of code
    }
}

注意:

以上并不完美,例如,您必须再运行循环 1 次才能考虑任何不能被 50 整除的记录集,但如果它能被 50 整除,您不想再次循环(可能是我们 mod 运算符来确定是否有余数,如果有,则添加 1(。