我有一些离子段按钮,基本上作为切换开关。我试图限制切换的影响,可以切换/选择的速度),并尝试去反弹和节流从两个破折号和现在下划线没有成功。
我目前正在使用下划线,尽管使用了去反跳功能,但仍然存在该函数被自由调用的问题。
下面是我的代码:
const SensorMeasurements: React.FC = () => {
//.....
const setOptionsHandler = (value: string, option: string, key: string) => {
if (value === "true") {
console.log("RESULT: True / " + value + " / " + option + " / " + key);
if (!settingsHandler(key)) {
setControlHandler(option, false); //toggle on
console.log("TOGGLE " + option + " ON!");
}
}
else { // false
console.log("RESULT: False / " + value + " / " + option + " / " + key);
if (settingsHandler(key)) {
setControlHandler(option, false); //toggle off
console.log("TOGGLE " + option + " OFF!");
}
}
}
const setOptionsHandlerThrottled = _.debounce(setOptionsHandler, 5000, true);
const setControlHandler = async (input: string, notify?: boolean) => {
let sysCommand = "";
switch (input) {
case "Reset":
sysCommand = "R";
break;
case "Test":
sysCommand = "T";
break;
case "Calibration":
sysCommand = "B";
break;
case "Logging":
sysCommand = "L";
break;
case "Trigger":
sysCommand = "H";
break;
case "Measuring":
sysCommand = "M";
break;
case "Unit":
sysCommand = "U";
break;
}
try {
const abControl = str2ab(sysCommand);
const dvControl = new DataView(abControl.buffer);
//console.log("CONTROL BUFFER", abControl);
await BleClient.initialize();
//if (isAndroid && (devices.deviceId ?? true)) {
// await BleClient.getDevices(devices.deviceId);
// await BleClient.disconnect(devices.deviceId);
//}
await BleClient.getDevices(devices.deviceId);
await BleClient.connect(devices.deviceId, (deviceId) => onDisconnect(deviceId));
await BleClient.write(devices.deviceId, SERV_SYSTEM_CONTROL, CHAR_OPERATIONAL_MODE, dvControl);
if (notify !== false) {
present(input + ' Command Sent.', 3000);
}
} catch (error) {
CatchError(error, "Disconnected");
}
}
const settingsHandler = (string: string) => {
return trueOrFalse(iTrueStates, string) as unknown as string;
}
const trueOrFalse = (array: string[], string: string) => {
//check if string is in the array - returns boolean
return array.includes(string);
}
return (
<IonSegment onIonChange={e => setOptionsHandlerThrottled(e.detail.value as string, "Trigger", "statusSensorHighTrigger")} className="lowercase" color="brand" value={settingsHandler("statusSensorHighTrigger")}>
<IonSegmentButton value="false">
<IonLabel>Low</IonLabel>
</IonSegmentButton>
<IonSegmentButton value="true">
<IonLabel>High</IonLabel>
</IonSegmentButton>
</IonSegment>
);
export default SensorMeasurements;
当IonSegmentButton改变时,为什么setOptionsHandler
仍然被调用,而不管去抖超时?我是否在每次调用它时都意外地创建了一个新的去抖函数?
2条答案
按热度按时间hjzp0vay1#
As you guessed, the problem is that you are creating a new debounced function every time the component is rendered. The multiple debounced functions are unaware of each other's timeouts. If we omit the other code for clarity, the problem is relatively easy to see:
The simple solution is to use a class component instead. By creating the debounced function in the constructor, it can be retained between renderings. Most other functions can be free-standing at module scope, since they do not depend on component state.
Do note that if the instance of the component is replaced as a whole (for example because a containing component is re-rendered), the timeout will still be reset. In that case, you might need to lift the debounced function into the larger component.
A possible alternative to using
_.debounce
would be to use thedebounce
operator from RxJS. In that case, a similar consideration would apply that you might need to lift the subject to a larger containing component.In the comments, you stated that the problem went away when you removed the
async
/await
syntax from thesetControlHandler
function. I cannot explain this; with your original code, you will create a new debounced function on each render regardless. I suspect some other, unrelated bug is preventing the event handler from triggering again in that case.As an encore, I would like to show you a cleaner way to write your
setControlHandler
function:wljmcqd82#
最后,我最终使用了AwesomeDebouncePromise,因为这是最好的。为了防止每次重新渲染都创建一个新的Debounced函数,我将debounced函数 Package 在一个useMemo中。