优化数据循环

时间:2014-04-28 23:36:50

标签: javascript slickgrid

我有一个20,000-150,000行的网格,点击后我可以选择所有,然后我用这个电话来批准它们。
这适用于少于1000行,但是除了浏览器锁定之外,甚至在我单独放置20分钟之后永远不会完成。

我正在寻找能够优化此过程的解决方案。

$("#approval").on('click',function(){
    var thisgrid = Grid; //my gridwapper
    var spotrows = thisgrid.grid.getSelectedRows();

    var index = 0;

    // console.dir(spotrows);

    if(typeof spotrows.length == 'undefined' || spotrows.length == 0)
    {
        alert('Please select a spot.');
        return;
    }

     for(key in spotrows)
     {

     var spotupdate = {};

     thisgrid.grid.invalidateRow(spotrows[key]);
     spotupdate = thisgrid.dataview.getItem(spotrows[key]);
     spotupdate['Approved'] = (spotupdate['Approved'] == 1) ? 0 : 1;

     thisgrid.dataview.updateItem(spotupdate['id'],spotupdate);


     }
    thisgrid.dataview.refresh();


});

2 个答案:

答案 0 :(得分:1)

浏览器锁定的原因是因为Javascript(和UI)在单个线程中运行。这意味着,只要代码正在执行,浏览器就无法处理UI事件(点击,重新绘制等)。

在保持UI响应的同时处理大量数据的方法是将循环分解为多个较小的函数调用,并使用setTimeout对下一个循环段进行排队。像这样:

$("#approval").on('click',function(){
    var thisgrid = Grid; //my gridwapper
    var spotrows = thisgrid.grid.getSelectedRows();

    function iterate(rows){
        var max = 1000, count = 0;
        for(key in rows){
            // do stuff

            delete rows[key];
            count++;
            if(count == max) {
                setTimeout(function(){
                    iterate(rows);
                }, 0);
                break;
            }
        }
    }

    iterate(spotrows);

});

即使将超时设置为0毫秒,这仍然有效,因为setTimeout确保在下一次JS事件循环传递时调用该函数,从而为其他排队事件提供处理的机会

有关JS事件循环的更多信息 - http://blog.carbonfive.com/2013/10/27/the-javascript-event-loop-explained/

答案 1 :(得分:0)

我尝试过使用setTimeout并没有提高性能。

这是我使用的解决方案。 经过几次测试后,我发现了以下几行,因为它们似乎不需要:

  

thisgrid.grid.invalidateRow(spotrows [键]);

     

thisgrid.dataview.refresh();

并补充说非常重要:

  

thisgrid.dataview.beginUpdate();

  

thisgrid.dataview.endUpdate();

以下是完整的参考代码: 这允许在不到2秒的时间内更新100,000行。

$("#approval").on('click',function(){
    var thisgrid = Grid; //my gridwapper
    var spotrows = thisgrid.grid.getSelectedRows();

    var index = 0;


    if(typeof spotrows.length == 'undefined' || spotrows.length == 0)
    {
        alert('Please select a spot.');
        return;
    }
    thisgrid.dataview.beginUpdate();
    for(key in spotrows)
    {

       var spotupdate = {};

       thisgrid.grid.invalidateRow(spotrows[key]);
       spotupdate = thisgrid.dataview.getItem(spotrows[key]);
       spotupdate['Approved'] = (spotupdate['Approved'] == 1) ? 0 : 1;

       thisgrid.dataview.updateItem(spotupdate['id'],spotupdate);
       delete spotupdate;
       delete spotrows[key];


     }

    thisgrid.dataview.endUpdate();


});