车辆控制解决方案
/*
* @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
,这可能导致不同的点击事件之间的混淆和冲突。