You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ionic/Angular语音转文本:如何阻止异步进程并发执行

问题解决:Ionic/Angular语音转文本并发冲突问题

问题场景

在Ionic/Angular应用中,使用Capacitor SpeechRecognition插件实现两个独立textarea的语音转文本功能。但出现以下异常:启动Reflection录音并停止后,再启动learningPlan录音时,两个textarea会同时更新为learningPlan的语音内容。

问题原因

每次调用startSpeechRecognition时,都会新增一个partialResults事件监听器,但停止录音时没有移除之前添加的监听器。旧的监听器仍然会响应语音识别的结果,导致多次触发不同textarea的更新逻辑,最终出现两个输入框同时被修改的情况。从控制台日志也能看出,启动learningPlan录音后,Reflection对应的监听器还在输出日志,说明它仍在工作。

解决方案

核心思路是管理监听器的生命周期:每次启动录音时保存监听器引用,停止录音时移除该监听器,确保同一时间只有一个监听器在工作。

步骤1:添加监听器引用变量

在组件类中添加变量,用于存储当前的语音识别监听器引用:

private speechListener: any; // 存储当前的监听器引用

步骤2:修改启动录音函数

启动录音前先移除可能存在的旧监听器,再添加新监听器并保存引用:

async startSpeechRecognition(textArea: string) {
  console.log("Eventmodal - SpeechRec called for textarea : ", textArea, "  called");
  const { available } = await SpeechRecognition.available();

  if (available && !this.recordingVoice) {
    this.recordingVoice = true;
    // 先移除之前的监听器(如果存在)
    if (this.speechListener) {
      this.speechListener.remove();
    }

    await SpeechRecognition.start({
      popup: true,
      partialResults: true,
      language: 'en-uk',
    });

    // 保存新的监听器引用
    this.speechListener = SpeechRecognition.addListener('partialResults', (data: any) => {
      console.log("Event odal SpeechRec- txtearea = ", textArea);
      
      if (data.matches) {
        if (textArea === "Reflection") {
          console.log("EventModal - SpecchToText BUTTON- txt area Learning Outcome/Reflection  called : ", textArea);
          this.uploadEvent.reflection = data.matches[0];
          this.specchToText = data.matches[0];
          this.changeDetectorRef.detectChanges();
        } else {
          console.log("EventModal - SppechToText BUTTON- txt area Imapct on Practice/Learning Plan called ");
          this.uploadEvent.learningPlan = data.matches[0];
          this.specchToText = data.matches[0];
          this.changeDetectorRef.detectChanges();
        }
      }

      // 兼容Android插件2.1版本的结果格式
      if (data.value && data.value.length > 0) {
        this.specchToText = data.value[0];
        this.changeDetectorRef.detectChanges();
      }
    });
  }
}

步骤3:修改停止录音函数

停止录音时移除当前监听器并清空引用:

async stopSpeechRecording() {
  this.recordingVoice = false;
  await SpeechRecognition.stop();
  // 移除监听器
  if (this.speechListener) {
    this.speechListener.remove();
    this.speechListener = null;
  }
}

步骤4:组件销毁时清理监听器

为防止内存泄漏,在组件销毁时确保监听器被移除:

ngOnDestroy() {
  if (this.speechListener) {
    this.speechListener.remove();
  }
}

验证效果

修改后,每次启动新录音前都会移除旧监听器,停止录音时也会清理当前监听器,确保同一时间只有一个监听器处理语音识别结果,两个textarea的更新逻辑不会互相干扰。

内容的提问来源于stack exchange,提问作者dancingbush

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 09:05:59