我正在开发一种可以通过语音识别模块控制的 React Formik 表单。
我在设置返回的成绩单时遇到一个问题,因为它试图设置状态太快。我尝试添加去抖/节流,但它似乎仍然被调用。
还有一些错误,例如美式英语/英式英语,语音有时返回“one”而不是“1”,并且表单字段本身对整数或字符串值敏感。
https://codesandbox.io/s/wispy-fog-fsjy64?file=/src/index.js
VoiceControlledForm - 连接语音模块和 formik 表单之间的桥梁。
textAnalysis(transcriptText) 是获取语音文本并将其转换为命令对象以控制表单(如果成功)的地方 - 需要在此处进行验证和微调 - //当前已设置一个覆盖它的值来测试
过程分析(笔录、听力)
我尝试仅在该人停止说话后才调用表单控制/语音分析。我添加了这个节流函数,它似乎有所帮助,但没有中断 - 但节流函数需要停止调用 - 我似乎无法稳定系统。
console.log("===========><transcript", transcript);
if(transcript.length>0 && !listening){
console.log("WORDS ARE BEING SPOKEN");
var that = this;
var myEfficientFn = throttle(function() {
console.log("CALLLLED CALLLED");
that.textAnalysis(transcript)
}, 1500);
if(!listening){
myEfficientFn();
}
}
以下是一些稳定系统并防止状态更新过于频繁的方法:
1.Increase throttle timeout
当前的 1500ms 超时可能仍然太短。尝试将其增加到 3000-5000 毫秒,以确保语音识别有时间完成每个话语。
2.Add debounce instead of throttle
const debouncedAnalysis = debounce(this.textAnalysis, 3000)
debouncedAnalysis(transcript);
通过去抖动,快速调用将被合并在一起,而不是调用计时器上的最后一个调用。这避免了中间状态更新。
3. Batch state updates
您可以将转录本批量放入缓冲区,并在缓冲区达到特定阈值后更新状态,而不是在每次调用时更新状态。
let transcriptBuffer = []
const handleTranscript = (transcript) => {
transcriptBuffer.push(transcript)
if (transcriptBuffer.length >= 5) {
this.setState({
transcripts: transcriptBuffer
})
transcriptBuffer = []
}
}
将语音识别逻辑提取到单独的组件/模块中,无需直接状态更新。然后让它发出可以在更新状态之前消除抖动的事件/回调。
这将频繁的脚本更新与屏幕上呈现的组件状态分开。关键是在两者之间插入一些缓冲/去抖动层。如果这些想法有帮助或者您有任何其他问题,请告诉我!