车辆控制解决方案
/*
* @Purpose: 优化车辆控制的功能 -> 用户在控制车辆状态时,实现控制按钮点击状态改变只触发一次onSwitchChange事件,不再下发控制指令,同时清除加载车辆实时状态的定时器status_interval直到有返回值再开启,并且给重新开启定时器这个操作加一个7秒延时,确保控制按钮不会发生跳变。
* @File Name: 车辆控制解决方案
* @Author: Caroline
* @Modifications: 2023/12/08
*/
bd_vehicle.js
车辆控制优化代码
function loadVehicleStatus() {...$.post(app_ctl + '/status', {option: 0,application_id: application_id_val,obu_id: obu_id_val,demo_flag: demo}, function (data, status) {if(data){}if (status == "success" && data && data.request == "success") {...if (lastDateTime == "" || lastDateTime != newDateTime) {...$.each(oJson, function (key, value) {...if(car_states[key]!=undefined){var img_id = car_states[key];img_state = value;if(img_state =="1" || img_state ==1){ $('#car-'+img_id).show();$('#'+img_id).bootstrapSwitch('state', true, true); }else{$('#car-'+img_id).hide();$('#'+img_id).bootstrapSwitch('state', false, true); } } });...} else {console.log("car-status response the data with same time.(", newDateTime, ")");}} else {console.log("car-status error!", data);}statueUpdateFlag = false; });
}$(function () {... $("[name='cbx-control']").bootstrapSwitch({onText: "开启",offText: "关闭",onColor: "success",offColor: "info",size: "mini",onSwitchChange: function (event, state) {id = $(this).attr("id")var option_val = state; if (status_timeout) clearTimeout(status_timeout);clearInterval(status_interval);$.post(app_ctl + '/control', {control_id: id,option: option_val,obu_id: obu_id_val}, function (data, status) {if (status == "success" && data && data.request == "success") {console.log(data.msg);controlStatus[id] = state;$("#" + html_pref + id).html(state ? "开启" : "关闭");} else {console.log("car-control error!", data);}status_timeout = setTimeout(function() {status_interval = setInterval(loadVehicleStatus, 3000);}, 7000);});}});var systemReadStatusInterval = setInterval(function () {...}, 1000);var status_interval = setInterval(loadVehicleStatus, 3000);console.log("system init.");
});
问题总结
1. 车辆控制优化点一
- 实现控制按钮点击状态改变只触发一次onSwitchChange事件,之后只读取后端状态显示,不再触发onSwitchChange事件。
- 其中bootstrapSwitch插件:
state
方法的第三个参数为可选参数skip
,如果为true,onSwitchChange
事件将不被执行,默认值为false。第二个参数为可选参数skip
,如果为true,switchChange
事件将被执行,false不执行。
if(img_state =="1" || img_state ==1){ $('#car-'+img_id).show();$('#'+img_id).bootstrapSwitch('state', true,true);
}
else{$('#car-'+img_id).hide();$('#'+img_id).bootstrapSwitch('state', false,true);
}
2. 车辆控制优化点二
- onSwitchChange事件执行后清除加载车辆实时状态的定时器status_interval,收到后端返回结果后再开启这个定时器。
var status_timeout;
onSwitchChange: function (event, state) {id = $(this).attr("id")var option_val = state; if (status_timeout) clearTimeout(status_timeout);clearInterval(status_interval);$.post(app_ctl + '/control', {control_id: id,option: option_val,obu_id: obu_id_val}, function (data, status) {if (status == "success" && data && data.request == "success") {console.log(data.msg);controlStatus[id] = state;$("#" + html_pref + id).html(state ? "开启" : "关闭");} else {console.log("car-control error!", data);}status_timeout = setTimeout(function() {status_interval = setInterval(loadVehicleStatus, 3000);}, 7000);});
}
3. 车辆控制优化点三
- 给控制按钮加一个延时操作,onSwitchChange事件执行后给清除加载车辆实时状态的定时器status_interval添加setTimeout7秒延时,status_interval定时器依旧为三秒请求一次status状态
- 其次,避免多次点击均触发延时操作,所以每一次点击control状态改变都清除延时器clearTimeout(status_timeout)
- 对status_timeout进行判空操作
- status_timeout的声明,一定要为外部变量,局部变量会导致,每次点击按钮都会重新声明status_timeout,要确保多次点击之间的一致性。
- 如果
status_timeout
是在 onSwitchChange
函数内声明的局部变量,每次点击按钮时都会重新声明。这就导致了在一个点击事件完成之前,新的点击事件会创建一个新的 status_timeout
,这可能导致不同的点击事件之间的混淆和冲突。