购物清单项目SpeechRecognition语音识别功能两个bug排查问询
问题分析与修复方案
问题1:点击停止按钮后无法立刻终止识别
原因
- 停止按钮的点击逻辑仅修改了
click状态变量,未主动调用recognition.stop()方法,依赖end事件回调触发停止操作。此时如果已有语音片段进入识别处理队列,会先触发result事件完成本次商品录入,才会触发end事件执行停止,因此会多出1条录入记录。 - 状态变量
click的判断逻辑存在歧义:end事件回调中click为true时才执行停止,而点击停止按钮第一次才将click赋值为true,中间存在处理时序差。
修复方案
停止按钮点击时直接调用识别停止方法,同步修改状态:
stopSpeechBtn.addEventListener('click', function () { click = true; recognition.stop(); console.log(click); console.log(recognition); })
同时建议将变量click重命名为isRecognitionStopped,避免逻辑歧义,启动识别时将其赋值为false即可。
问题2:重启识别后重复录入商品
原因
result事件的绑定逻辑写在addProductViaSpeech函数内部,每次点击语音启动按钮都会给recognition对象新增一个result监听器,多次点击就会绑定多个相同回调。后续触发一次result事件时,多个回调会同时执行,就会出现录入1次、新增多条商品的问题。
修复方案
将result事件的绑定逻辑移到全局,仅执行1次绑定即可:
// 全局绑定一次result监听,不要放在addProductViaSpeech内部 recognition.addEventListener('result', e => { // 原result回调逻辑保持不变 const transcript = Array.from(e.results).map(result => result[0]).map(result => result.transcript).join(''); console.log(transcript); if (e.results[0].isFinal) { const productDiv = document.createElement("div"); productDiv.classList.add("product"); const newProduct = document.createElement('li'); newProduct.innerText = transcript; newProduct.classList.add('product-text'); productDiv.appendChild(newProduct); //local storage console.log(newProduct.innerText); saveLocalTodos(newProduct.innerText); const productPrice = document.createElement("li"); productPrice.classList.add("product-price"); const priceProductInput = document.createElement("input"); priceProductInput.classList.add("price-product-input"); priceProductInput.placeholder = "$"; productDiv.appendChild(productPrice); productPrice.appendChild(priceProductInput); const trashButton = document.createElement("button"); trashButton.innerHTML = '<i class="fas fa-times"></i>'; trashButton.classList.add("trash-btn"); productDiv.appendChild(trashButton); productList.appendChild(productDiv); productInput.value = ""; quantityJs++; quantity.innerText = quantityJs; productInput.classList.add("warning"); productInput.placeholder = "can't be empty"; for (let i = 0; i < arr.length; i++) { arr[i].addEventListener('change', findTotal); } } }); function addProductViaSpeech(event) { event.preventDefault(); console.log("dziala chwile"); click = false; recognition.start(); }
内容的提问来源于stack exchange,提问作者Jakub Sołdek
相关产品推荐
相关产品推荐

