首页 > 解决方案 > 如何在 1 个函数中多次调用语音识别?

问题描述

我对 JavaScript 比较陌生,目前正在从事一个初学者可能不应该开始的项目。我已经在 python 中编码了一段时间,并决定试一试。我正在尝试做一个私人助理,或者我喜欢称之为 Jarvis(来自 IRON MAN)。它目前可以侦听命令并很好地执行它们,但是,我正在尝试制作一个send email命令,该命令需要用户在一个函数中进行多次输入。这个发送电子邮件功能在技术上是parseCommand()在我传递标识符的地方,称为 i。我最终将添加更多命令,parseCommand()标识符将有助于了解要执行的命令。当我说“jarvis 发送电子邮件”时,parseCommand("email")它被称为。这是一个承诺,因为一旦完成,我想再次调用 annyang(命令侦听器)。

当“jarvis 发送电子邮件”被触发时 ->

"jarvis send an email" : async function(){
  annyang.abort(); // stop listening
  await parseCommand("email").then(annyang.start()); // Start listening for another command when done
}

解析命令:

parseCommand(i){
    return new Promise(async (resolve) => {
        recognition.stop();



        if(i == "email"){
            var SUBJECT;
            var TEXT;
            var TO;

            console.log("Running: send an email")
            await this.promptListen("Who shall I send it to?").then( async (email) =>{
                TO = email;
                console.log("got TO", TO)

                await this.promptListen("What shall the subject be?").then( async (subject) => {
                    SUBJECT = subject;
                    console.log("got SUBJECT", SUBJECT)

                    await this.promptListen("What would you like to say?").then((text) => {
                        TEXT = text;
                        console.log("got TEXT", TEXT)
                        resolve()
                        })
                    })
                });
            }
        })
    }

提示监听命令:

promptListen(prompt){
        return new Promise((resolve, reject) => {
            socket.emit("speak", prompt);
            setTimeout(1000);

            promptRecognition.stop(); // NOTE #1

            promptRecognition.start();

            promptRecognition.onresult = function(event){
                console.log(event)
                promptRecognition.stop();
                resolve(event.results[0][0].transcript);
            }
            promptRecognition.onnomatch = function() {
                promptRecognition.stop();
                reject(promptListen(prompt));
            }
        })

    }

当前功能的问题是它根本不起作用。系统提示我“我应该将它发送给谁?” 贾维斯听着。我得到 TO 控制台输出,但是,之后我得到一个错误:

responses.js:63 Uncaught (in promise) DOMException: Failed to execute 'start' on 'SpeechRecognition': recognition has already started.
    at Promise (http://localhost:3000/scripts/responses.js:63:31)
    at new Promise (<anonymous>)
    at Respond.promptListen (http://localhost:3000/scripts/responses.js:57:16)
    at promptListen.then (http://localhost:3000/scripts/responses.js:41:28)

该错误表明我已经在运行 SpeechRecognition,但是,promptListen()为了以防万一,我在每次开始时都会停止它。我根本不知道发生了什么事。期望的结果是每次调用promptListen()都允许我提示用户、听取响应、将响应存储在变量中:对于发送电子邮件所需的每个变量(收件人、主题和正文)。我不熟悉 JavaScript、promise、async 或 await。我已经尝试了所有可能的变体,并且查看了文档但无济于事。如果我不使用 Promise,promptListen()则会同时为收件人、主题和正文提示调用该函数。这就是为什么我决定尝试用 Promise 来解决这个问题。任何帮助表示赞赏 - 谢谢!

标签: javascriptpromiseasync-awaitspeech-recognitionannyang

解决方案


我的代码理论上有效。问题是,或者至少我认为是,当我打电话时then promptRecoginition.stop()需要时间停下来。我立即.start()再次呼叫下一个提示,一旦我解决了最近的问题promptListen(),因此promptRecognition没有时间.stop()。我发现可行的解决方案是:

setTimeout( async () => {
    await this.promptListen("What shall the subject be").then( (subject) => {
        SUBJECT = subject;
        // Add another setTimeout here
    }
}, 1000);

使用 setTimeout 函数,我给promptRecognition了时间.stop()并继续没有任何错误。


推荐阅读