我的博览会应用程序遇到问题。如果间隔被超时清除,则没有问题,但如果触发,则下一步将以双倍速度运行。我不明白有什么问题。
const stepInterval = setInterval(() => {
setStepCountdown((prev) => {
if (triggeredInStep.current){
turnOffAllNodes();
console.log("Triggered in step");
clearInterval(stepInterval);
if (currentStep < selectedSteps) {
setDelayCountdown(selectedDelay);
}
return 0;
}
if (prev <= 0.1) {
clearInterval(stepInterval);
setIncorrectCount((prev) => prev + 1);
console.log("Incorrect timeout, turning off all nodes and not triggered in step");
turnOffAllNodes();
if (currentStep < selectedSteps) {
setDelayCountdown(selectedDelay);
}
return 0;
}
return Math.max(prev - 0.1, 0);
});
}, 100);
它应该每100毫秒更新一次,但是当触发上一步并且没有超时时,它会以双倍速度进行
好的,所以我找到了问题。我会发布它,因为它可能会帮助将来的人。
间隔的逻辑很好。问题出在蓝牙钩子和这个
useEffect
的交互上。在问题中,我只是放置了处理计时器的代码部分,但这是由步骤更改触发的 useEffect
内部(应用程序有多个步骤,您必须在其中触发节点,这些节点是发送消息的 PCB)通过 BLE/MESH)。
所以...在
useEffect
开始时,我将triggeredDevice
设置为null
,这样如果它与上一步相同,它将强制应用程序将其解释为已更改,从而触发其useEffect
(不是这个,是另一个)。
useEffect(() => {
if (currentStep <= selectedSteps) {
const selectedArray = Array.from(selectedDevices);
const masterDevice = selectedArray[0];
setTriggeredDevice(null); // <--- This I had to comment out
const randomIndex = Math.floor(Math.random() * selectedArray.length);
const selectedCorrectDevice = selectedArray[randomIndex];
这与 BLE 钩子中的读取特征函数中该状态的设置“冲突”:
const startListeningToCharacteristic = async (device: Device, characteristicUUID: string) => {
if (device) {
try {
if (isDeviceConnected(device.id)) {
const subscription = device.monitorCharacteristicForService(
TERMINAL_UUID_SERVICE,
characteristicUUID,
(error, characteristic) => {
if (characteristic?.value) {
const decodedData = base64.decode(characteristic.value);
console.log(`Received data: ${decodedData}`);
try {
const parsedData = JSON.parse(decodedData);
const deviceId = parsedData.node;
setTriggeredDevice(""); // This I added to force the trigger
setTriggeredDevice(deviceId);
} catch (parseError) {
console.error("Error parsing JSON data:", parseError);
}
} else {
console.log("No Data received");
}
}
);
characteristicSubscriptions.current[device.id] = subscription;
} else {
console.log(`Device ${device.id} is not connected.`);
listConnectedDevices();
}
} catch (error) {
console.error("Error during monitoring setup:", error);
}
} else {
console.log("No Device Connected");
}
};
所以我在
deviceId
设置之前添加了空字符串设置来强制它,并且 setInterval
完美运行。我不完全理解为什么会出现这个问题,但我认为这可能是某种竞争条件或类似的东西。