Javascript 使用jQuery和Node在DOM上填充数据的最佳方法

Javascript 使用jQuery和Node在DOM上填充数据的最佳方法,javascript,jquery,node.js,dom,socket.io,Javascript,Jquery,Node.js,Dom,Socket.io,我正在使用节点的Socket.io将数据从服务器推送到客户端浏览器。 在客户机上,我使用jQuery填充DOM中返回的行 下面是我用来填充Socket.io返回的数据的代码段 var OverSpeedAlerts = []; var TripCancellation = []; var GeofenceInOutAlerts = []; var ScheduleOverstay = []; var UnSchduledOverstay = []; var SkippedBusStop = []

我正在使用节点的
Socket.io
将数据从服务器推送到客户端浏览器。 在客户机上,我使用jQuery填充DOM中返回的行

下面是我用来填充Socket.io返回的数据的代码段

var OverSpeedAlerts = [];
var TripCancellation = [];
var GeofenceInOutAlerts = [];
var ScheduleOverstay = [];
var UnSchduledOverstay = [];
var SkippedBusStop = [];
var TripDelayAlert = [];

var SkippedUnplannedAlert = [];
var DelayStartEndAlert = [];
var RouteDeviatedAlert = [];

var MultipleBusEntry = [];
声明原型:

Array.prototype.inArray = function (comparer) {
    for (var i = 0; i < this.length; i++) {
        if (comparer(this[i])) return true;
    }
    return false;
};

// adds an element to the array if it does not already exist using a comparer 
// function
Array.prototype.pushIfNotExist = function (element, comparer) {
    if (!this.inArray(comparer)) {
        this.unshift(element);
    }
};
if (typeof io !== 'undefined') {
    var pushServer = io.connect('http://SomeIP:3000');
    pushServer.on('entrance', function (data) {
        var rows = data.message;
        var NumberOfRows = rows.length;
        $('#notifications').html(NumberOfRows);
        // console.log(rows);
        OverSpeedAlerts = [];
        TripCancellation = [];
        GeofenceInOutAlerts = [];
        ScheduleOverstay = [];
        UnSchduledOverstay = [];
        SkippedBusStop = [];
        TripDelayAlert = [];

        SkippedUnplannedAlert = [];
        DelayStartEndAlert = [];
        RouteDeviatedAlert = [];

        var MultipleBusEntry = [];
        for (var i = 0; i < rows.length; i++) {
            if (rows[i].alert_type == 'overspeed') {
                OverSpeedAlerts.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }
            else if (rows[i].alert_type == 'trip_cancellation') {
                TripCancellation.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }
            else if (rows[i].alert_type == 'Geofence-In' || rows[i].alert_type === 'Geofence-Out') {
                GeofenceInOutAlerts.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }
            else if (rows[i].alert_type == 'Scheduled-Overstay') {
                ScheduleOverstay.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }
            else if (rows[i].alert_type == 'Unscheduled-Overstay') {
                UnSchduledOverstay.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }
            else if (rows[i].alert_type == 'Skipped Unplanned' || rows[i].alert_type == 'Skipped-Busstop') {
                SkippedBusStop.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }
            else if (rows[i].alert_type == 'Delay Start' || rows[i].alert_type == 'Delay End') {
                TripDelayAlert.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }
            else if (rows[i].alert_type == 'Route Deviated') {
                RouteDeviatedAlert.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }
            else if (rows[i].alert_type == 'Multiple Bus Entry') {
                MultipleBusEntry.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }

        }
        CreateOverSpeedGrid();
        CreateTripCancellation();
        CreateGeofenceGrid();
        CreateScheduleOverstayGrid();
        CreateUnSchduledOverstayGrid();
        CreateTripDelayGrid();
        CreateSkippedBusStop();
        CreateRouteDeviationAlert();
        CreateMultipleBusEntry();
    });
    pushServer.on('end', function (socket) {

    });
}

Array.prototype.inArray=函数(比较器){
for(var i=0;i
处理从套接字接收的数据:

Array.prototype.inArray = function (comparer) {
    for (var i = 0; i < this.length; i++) {
        if (comparer(this[i])) return true;
    }
    return false;
};

// adds an element to the array if it does not already exist using a comparer 
// function
Array.prototype.pushIfNotExist = function (element, comparer) {
    if (!this.inArray(comparer)) {
        this.unshift(element);
    }
};
if (typeof io !== 'undefined') {
    var pushServer = io.connect('http://SomeIP:3000');
    pushServer.on('entrance', function (data) {
        var rows = data.message;
        var NumberOfRows = rows.length;
        $('#notifications').html(NumberOfRows);
        // console.log(rows);
        OverSpeedAlerts = [];
        TripCancellation = [];
        GeofenceInOutAlerts = [];
        ScheduleOverstay = [];
        UnSchduledOverstay = [];
        SkippedBusStop = [];
        TripDelayAlert = [];

        SkippedUnplannedAlert = [];
        DelayStartEndAlert = [];
        RouteDeviatedAlert = [];

        var MultipleBusEntry = [];
        for (var i = 0; i < rows.length; i++) {
            if (rows[i].alert_type == 'overspeed') {
                OverSpeedAlerts.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }
            else if (rows[i].alert_type == 'trip_cancellation') {
                TripCancellation.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }
            else if (rows[i].alert_type == 'Geofence-In' || rows[i].alert_type === 'Geofence-Out') {
                GeofenceInOutAlerts.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }
            else if (rows[i].alert_type == 'Scheduled-Overstay') {
                ScheduleOverstay.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }
            else if (rows[i].alert_type == 'Unscheduled-Overstay') {
                UnSchduledOverstay.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }
            else if (rows[i].alert_type == 'Skipped Unplanned' || rows[i].alert_type == 'Skipped-Busstop') {
                SkippedBusStop.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }
            else if (rows[i].alert_type == 'Delay Start' || rows[i].alert_type == 'Delay End') {
                TripDelayAlert.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }
            else if (rows[i].alert_type == 'Route Deviated') {
                RouteDeviatedAlert.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }
            else if (rows[i].alert_type == 'Multiple Bus Entry') {
                MultipleBusEntry.pushIfNotExist(rows[i], function (e) {
                    return e.device_id === rows[i].device_id && e.alert_gen_date_time === rows[i].alert_gen_date_time;
                });
            }

        }
        CreateOverSpeedGrid();
        CreateTripCancellation();
        CreateGeofenceGrid();
        CreateScheduleOverstayGrid();
        CreateUnSchduledOverstayGrid();
        CreateTripDelayGrid();
        CreateSkippedBusStop();
        CreateRouteDeviationAlert();
        CreateMultipleBusEntry();
    });
    pushServer.on('end', function (socket) {

    });
}
if(io的类型!=“未定义”){
var pushServer=io.connect('http://SomeIP:3000');
pushServer.on('entry',函数(数据){
var rows=data.message;
var NumberOfRows=rows.length;
$('#notifications').html(NumberOfRows);
//console.log(行);
超速率=[];
TripCancellation=[];
GeofenceInOutAlerts=[];
计划逾期逗留=[];
UnSchduledOverstay=[];
SkippedBusStop=[];
TripDelayAlert=[];
SkippedUnplandalert=[];
DelayStartEndAlert=[];
RoutedViatedAlert=[];
var MultipleBusEntry=[];
对于(变量i=0;i
上述功能之一如下所示。Rest是在DOM的其他部分填充数据的类似函数

function CreateOverSpeedGrid() {
    $('#tabs ul').find('a:contains("Overspeed Alerts")').html('OverSpeed Alerts(' + OverSpeedAlerts.length + ')');
    if (OverSpeedAlerts.length != 0) {
        $('#notifyOverspeed table').html('');
        $('#notifyOverspeed table').append('<tr class="ui-widget-header"> <th> Depot </th> <th> Route </th> <th> Schedule </th> <th> Trip Number </th><th>Trip Direction</th> <th> Alert Summary</th> <th> Alert Details </th> <th> Generated On </th> </tr>'); //new Date([UNIX Timestamp] * 1000);
        for (var i = 0; i < OverSpeedAlerts.length; i++) {
            $('#notifyOverspeed table').append('<tr> <td>' + OverSpeedAlerts[i].depot_name + '</td> <td>' + OverSpeedAlerts[i].route_name + '</td> <td>' + OverSpeedAlerts[i].schedule_no + '</td> <td>' + OverSpeedAlerts[i].trip_number + ' </td> <td>' + OverSpeedAlerts[i].trip_direction + '</td><td> ' + OverSpeedAlerts[i].alert_sub + ' </td> <td title="' + ConvertToValidTooltip(OverSpeedAlerts[i].alert_msg) + '" style="text-decoration:underline;cursor:pointer;"> ' + "Place mouse pointer to view message" + ' </td> <td>' + new Date(OverSpeedAlerts[i].alert_gen_date_time * 1000) + ' </td> </tr>');
        }
    }
}
函数CreateOverSpeedGrid(){
$('#tabs ul').find('a:contains(“OverSpeedAlerts”)).html('OverSpeedAlerts('+OverSpeedAlerts.length+'));
如果(过速极限长度!=0){
$('#表').html('');
$(“#notifyOverspeed table”).append(“‘车辆段路线计划行程编号’);//生成的行程方向警报摘要警报详细信息’;//新日期([UNIX时间戳]*1000);
对于(变量i=0;i
上面的代码工作正常。但问题是,由于每10秒从套接字接收到如此多的推送消息,浏览器无法处理如此多的数据并挂断


有没有更好的方法呢???

不知道你的应用程序的详细信息,我将假设你需要所有这些数据
var io /*some lib*/, pushServer, alertTypes, alterTypesMapping, $notifications, lookupCache;

//i use the -Length fields to store the "previous" length, so i know if the dom needs updating at all
// and what part is new, no need to re-render perfectly valid html
alertTypes = {
    OverSpeedAlerts: [],
    OverSpeedAlertsLength: 0,
    TripCancellation: [],
    TripCancellationLength: 0,
    GeofenceInOutAlerts: [],
    GeofenceInOutAlertsLength: 0,
    ScheduleOverstay: [],
    ScheduleOverstayLength: 0,
    UnSchduledOverstay: [], //scheduled? sorry ide with spelling check
    UnSchduledOverstayLength: 0,
    SkippedBusStop: [],
    SkippedBusStopLength: 0,
    TripDelayAlert: [],
    TripDelayAlertLength: 0,
    SkippedUnplannedAlert: [],
    SkippedUnplannedAlertLength: 0,
    DelayStartEndAlert: [],
    DelayStartEndAlertLength: 0,
    RouteDeviatedAlert: [],
    RouteDeviatedAlertLength: 0
};

//mapping from types to their lists (some types map to the same list)
alterTypesMapping = {
    'overspeed': 'OverSpeedAlerts',
    'trip_cancellation': 'TripCancellation',
    'Geofence-In': 'GeofenceInOutAlerts',
    'Geofence-Out': 'GeofenceInOutAlerts',
    'Scheduled-Overstay': 'ScheduleOverstay',
    'Unscheduled-Overstay': 'UnSchduledOverstay',
    'Skipped Unplanned': 'SkippedBusStop',
    'Delay Start': 'TripDelayAlert',
    'Delay End': 'TripDelayAlert',
    'Route Deviated': 'RouteDeviatedAlert',
    'Multiple Bus Entry': 'MultipleBusEntry'
};

//cache dom lookup
$notifications = $('#notifications');

//we serialize the relevant message parts into an unique id, used for de-duping
//<id> => <alert_type>|<device_id>|<alert_gen_date_time>
lookupCache = {};

function process_data (data) {
    var i, l, rows, id;
    rows = data.message;
    l = rows.length;

    //update dom row count
    $notification.html(l);

    for (i=0; i<l; ++i) {    //caching length in l, ++i is faster than i++
        id = rows[i].alert_type + '|' + rows[i].device_id + '|' + rows[i].alert_gen_date_time;
        if (!lookupCache[id]) {
            lookupCache[id] = 1;    //set it to truthy so next time around its there
            //not in cache push it to the relevant list
            //you used unshift here, that's essentially moving all other elements in the list one spot and
            //adding the new one at index 0 (speed O(n) eg increases with more elements in the list)
            //instead you can push the new element to the end, (speed O(1) constant speed)
            // and when iterating the list doing that in reverse
            alertTypes[alterTypesMapping[rows[i].alert_type]].push(rows[i]);
        }
    }
    updateDom();
}

function updateDom () {
    var keys, i, l, html;

    //here we check all length fields in the alertTypes and see if the actual list length
    //is greater than their -Length
    //if so we update the relevant dom

    keys = Object.keys(alertTypes);
    for (i=0, l=keys.length; i<l; ++i) {
        //skip the -Length keys
        if (keys[i].match('Length')) {
            continue;
        }
        //please add a data-type="<type>" to the a's, so much better to lookup by attribute instead of text matching content
        $('#tabs ul a[data-type="' + keys[i] + '"]').html(keys[i] + '(' + alertTypes[keys[i] + 'Length'] + ')');

        //since well only update the dom, i presume at this point there is a dom with the table with headers
        //(use thead and th for this please)
        //(and use tbody for a table's body)
        //now we iterate the new elements (from list.length back to key-Length)
        //j starts at the length of the list, and ends at m, the previous length
        //counting backwards
        html = [];
        for (j=alertTypes[keys[i]].length, m=alertTypes[keys[i] + 'Length']; j>m; --j) {
            //array join is almost always faster than string concatenation
            //since strings are not mutable in js (eg. you create a new string every +)
            html.push([
                '<tr>',
                    '<td>',
                        alertTypes[keys[i]].depot_name,
                    '</td>',
                    '<td>',
                        alertTypes[keys[i]].route_name,
                    '</td>',
                    '<td>',
                        alertTypes[keys[i]].schedule_no,
                    '</td>',
                    '<td>',
                        alertTypes[keys[i]].trip_number,
                    '</td>',
                    '<td>',
                        alertTypes[keys[i]].trip_direction,
                    '</td>',
                    '<td>',
                        alertTypes[keys[i]].alert_sub,
                    '</td>',
                    '<td ',
                       'title="',
                            ConvertToValidTooltip(alertTypes[keys[i]].alert_msg),
                        '" style="text-decoration:underline;cursor:pointer;">Place mouse pointer to view message',
                    '</td>',
                    '<td>',
                        new Date(OverSpeedAlerts[i].alert_gen_date_time * 1000),
                    '</td>',
                '</tr>'
            ].join(''));
        }
        //and finally we update the key-Length so next time well only add what is newer than what we are about to add
        alertTypes[kesy[i] + 'Length'] = alertTypes[keys[i]].length;
        //get the dom element we have to update
        $('#' + keys[i] + ' tbody').prepend(html.join(''));
    }
}

if (io !== undefined) {   //no need for typeof when checking undefined, check undefined directly with equality (eg. undefined === undefined)
    pushServer = io.connect('http://SomeIP:3000');
    pushServer.on('entrance', process_data);
}