for循环对大数据执行缓慢

时间:2014-11-29 23:29:29

标签: javascript jquery css jqgrid

我有一个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');

我从firefox获得此问题:

  

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

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

1 个答案:

答案 0 :(得分:0)

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

一个想法是找到一种方法来分割您处理的数据量。正如你所说,似乎问题是大量数据。有没有办法将数据分成“页面”并一次处理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
    }
}

注意:

上述情况并不完美,例如,你必须再运行一次循环来计算任何不能被50整除的记录集,但如果它可以被50整除则你不想再次循环(可能是我们的mod运算符,用于确定是否有余数,然后如果存在则加1)。