如何在 1 个函数中多次调用语音识别?

How can I call Speech Recognition multiple times in 1 function?

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

当"jarvis send an email"被触发时->

"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));
            }
        })

    }

当前功能的问题是它根本不起作用。我被提示输入 "Who shall I send it to?" 并且 Jarvis 听了。我得到了 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() 都允许我提示用户、收听响应、将响应存储在变量中:对于发送电子邮件所需的每个变量(收件人、主题和body)。我不熟悉 JavaScript、promises、async 或 await。我已经尝试了所有可能的变体,也查看了文档但无济于事。如果我不使用 promises,promptListen() 函数会同时为收件人、主题和 body 提示调用。这就是为什么我决定尝试用承诺来解决问题。感谢任何帮助 - 谢谢!

我的代码在理论上是可行的。问题,或者至少我认为是,当我调用 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() 并继续没有任何错误。