4

在@kalley 的大力帮助下,我们发现如果我将以下两行注释掉,LAG 就消失了!

 var $tableContents = $table.find('tbody')
 var $html = $('<tbody/>').html(data);

但是我如何保留上述内容但取消 LAG ?


更多信息: 下面的代码有效,但问题是$.GET导致浏览器挂起,直到 ajax 请求完成。我需要(流控制?)或者可以在不锁定/挂起浏览器的情况下解决这个问题的东西,直到 ajax 完成 GET 请求。

最大的 LAG/Lockup/Hang 是 at $.get("updatetable.php",因为其他只返回 7 个或更少(数字)值,而这个('updatetable.php')返回更多(200-300kb)。我想在这里实现某种流控制,或者让脚本在触发 tablesort 的更新命令和显示 toast 消息之前等待 5 秒,以便 ajax 有时间获取$.get("updatetable.php"数据我只是不明白为什么这样做在获取数据时锁定浏览器?它是否试图触发其他命令,这就是导致 LAG 的原因?

以下是步骤

1. $.get("getlastupdate.php"每 10 秒左右触发一次,检查日期和时间是否相同,返回数据如下所示:20130812092636格式为:YYYmmddHHmmss。

2. 如果日期和时间与上一次 GET 不同,则$.get("getlastupdate2.php"触发,此数据将被发送回并放入 toast 消息中并显示给用户$().toastmessage('showNoticeToast', Vinfoo);

3. 在上述 ( $.get("getlastupdate2.php") 之前或之后,另一个 GET 将触发: $.get('updatetable.php'这将 GET 更新的表信息。并用新信息替换旧信息。然后更新/重新排序表格

4. 最后我想要的,$.get("ajaxcontrol.php"如果用户登录,这将返回 1 或 2,然后返回 2,否则返回 1,它会破坏会话并注销用户。

    <script type="text/javascript" src="tablesorter/jquery-1.10.2.min.js"></script> 
    <script type="text/javascript" src="tablesorter/final/jquery.tablesorter.js"></script>
    <script type="text/javascript" src="tablesorter/final/jquery.tablesorter.widgets.js"></script>
    <script type="text/javascript" src="tablesorter/final/toastmessage/jquery.toastmessage-min.js"></script>
    <script type="text/javascript" src="tablesorter/qtip/jquery.qtip.min.js"></script>

    <script type="text/javascript">
        var comper;
    function checkSession() {
        return $.get("ajaxcontrol.php", function (DblIn) {
            console.log('checking for session');
            if (DblIn == 1) {
                window.location = 'loggedout.php';
            }
        }).then(updateTable);
    }

    function checkComper() {
        var SvInfo;
        var onResponse = function (comperNow) {
            if (comper === undefined) {
                comper = comperNow;
            } else if (comper !== comperNow) {
                var Vinfoo;
                comper = comperNow;
                // returning this $.get will make delay done until this is done.
                return $.get("getlastupdate2.php", function (primaryAddType) {
                    Vinfoo = primaryAddType;
                    $().toastmessage('showNoticeToast', Vinfoo);
                }).then(checkSession);
            }
        };
        $.get('getlastupdate.php').then(onResponse).done(function () {
            tid = setTimeout(checkComper, 2000);
        });
    }


    function updateTable() {
        return $.get('updatetable.php', function (data) {
            console.log('update table');
var $table = $("table.tablesorter");
            var $tableContents = $table.find('tbody')
            var $html = $('<tbody/>').html(data);
              $tableContents.replaceWith('<tbody>' + data + '</tbody>')
            //$tableContents.replaceWith($html)
            $table.trigger("update", [true]);
            var currentUrl = document.getElementById("frmcontent").contentWindow.location.href;
            var urls = ['indexTOM.php', 'index1.php'],
                frame = document.getElementById('frmcontent').contentDocument;

            for (var i = 0; i < urls.length; i++) {
                var url = urls[i];
                if (frame.location.href.indexOf(url) !== -1) {
                    frame.location.reload()
                }
            }

            $('[title!=""]').qtip({});
        });

    };


    $(function () {
    var tid = setTimeout(checkComper, 2000);


    $("#append").click(function (e) {
        // We will assume this is a user action
        e.preventDefault();
        updateTable();
    });

            // call the tablesorter plugin
            $("table.tablesorter").tablesorter({
                theme: 'blue',
                // hidden filter input/selects will resize the columns, so try to minimize the change
                widthFixed: true,
                // initialize zebra striping and filter widgets
                widgets: ["saveSort", "zebra", "filter"],
                headers: {
                    8: {
                        sorter: false,
                        filter: false
                    }
                },
                widgetOptions: {
                    filter_childRows: false,
                    filter_columnFilters: true,
                    filter_cssFilter: 'tablesorter-filter',
                    filter_filteredRow: 'filtered',
                    filter_formatter: null,
                    filter_functions: null,
                    filter_hideFilters: false, // true, (see note in the options section above)
                    filter_ignoreCase: true,
                    filter_liveSearch: true,
                    filter_reset: 'button.reset',
                    filter_searchDelay: 300,
                    filter_serversideFiltering: false,
                    filter_startsWith: false,
                    filter_useParsedData: false
                }
            });

            // External search
            $('button.search').click(function () {
                var filters = [],
                    col = $(this).data('filter-column'), // zero-based index
                    txt = $(this).data('filter-text'); // text to add to filter
                filters[col] = txt;
                $.tablesorter.setFilters($('table.hasFilters'), filters, true); // new v2.9
                return false;
            });
       });
    </script>
4

2 回答 2

2

也许setInterval您应该考虑改用setTimeout. 它可以让您更好地控制时间重复的时间:

function checkComper() {
    var SvInfo;
    var onResponse = function (comperNow) {
        if (comper === undefined) {
            comper = comperNow;
        } else if (comper !== comperNow) {
            var Vinfoo;
            comper = comperNow;
            // returning this $.get will make delay done until this is done.
            return $.get("getlastupdate2.php", function (primaryAddType) {
                Vinfoo = primaryAddType;
                $().toastmessage('showNoticeToast', Vinfoo);
            }).then(checkSession);
        }
    };
    $.get('getlastupdate.php').then(onResponse).done(function () {
        tid = setTimeout(checkComper, 10000);
    });
}

var tid = setTimeout(checkComper, 10000);

然后你可以保留它async: true

这是一个小提琴,显示它使用 echo.jsontest.com 和一些捏造的数字工作。

由于click事件回调似乎是问题所在,请尝试执行此操作并查看它是否消除了滞后(我删除了其他评论以使其更简短):

function checkSession() {
    return $.get("ajaxcontrol.php", function (DblIn) {
        console.log('checking for session');
        if (DblIn == 1) {
            window.location = 'loggedout.php';
        }
    }).then(updateTable);
}
function updateTable() {
    return $.get('updatetable.php', function (data) {
        console.log('update table');
        var $tableContents = $table.find('tbody')
        //var $html = $('<tbody/>').html(data);
        //$tableContents.replaceWith($html);

        // replaceWith text seems to be much faster:
        // http://jsperf.com/jquery-html-vs-replacewith/4
        $tableContents.replaceWith('<tbody'> + data + '</tbody>');

        //$table.trigger("update", [true]);
        var currentUrl = document.getElementById("frmcontent").contentWindow.location.href;
        var urls = ['indexTOM.php', 'index1.php'],
            frame = document.getElementById('frmcontent').contentDocument;

        for (var i = 0; i < urls.length; i++) {
            var url = urls[i];
            if (frame.location.href.indexOf(url) !== -1) {
                frame.location.reload()
            }
        }

        $('[title!=""]').qtip({});
    });

};

$("#append").click(function (e) {
    // We will assume this is a user action
    e.preventDefault();
    updateTable();
});

我注释掉了,$table.trigger("update", [true])因为如果您在返回之前对服务器上的表进行排序,则不需要运行它,我几乎可以肯定这是瓶颈所在。

于 2013-08-09T17:18:12.307 回答
1

真的很难解开你的混乱,但如果你想要的是每 10 秒一次的 ajax 请求,那么将这个逻辑与业务逻辑分开而不是来自服务器的数据是有意义的。

您的代码也将真正受益于使用承诺。考虑这个例子

 $(document).ready(function() {

     var myData = {  }
      , ajaxPromise = null


     setInterval(callServer, 1000)


     function callServer() {

        ajaxPromise = updateCall()
                       .then(controlCall)
                       .done(handler)
                       .error(errorHandler) 
     }
     function updateCall() {
       return $.get('updateTable.php', function(data) {
          myData.update = data
       })
     } 

     function controlCall( ) {
       return $.get('ajaxControl.php', function(data) {
          myData.control = data
       })
     }

     function handler() {
       console.dir(myData)
     }

     function errorHandler(err) {
        console.log(err)
        console.dir(myData)         
     }
 })
于 2013-08-09T17:13:38.877 回答