如何在1个功能中多次调用语音识别?

时间:2018-10-14 02:50:42

标签: javascript promise async-await speech-recognition annyang

我对JavaScript比较陌生,目前正在从事一个项目,可能不适合初学者。我已经用python编写了一段时间,并决定尝试一下。我试图做一个私人助理,或者我想称呼它为Jarvis(来自《钢铁侠》)。它当前可以监听命令并执行得很好,但是,我正在尝试制作一个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:

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命令:

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

    }

当前功能的问题在于它根本不起作用。系统提示我输入“我应该发送给谁?”。 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()的调用都会允许我提示用户,听取响应并将响应存储在变量中:对于发送电子邮件所需的每个变量(收件人,主题和身体)。我不熟悉JavaScript,promise,async或await。我尝试了所有可能的变体,也没有看文档。如果我不使用诺言,则收件人,主题和正文提示会同时调用promptListen()函数。这就是为什么我决定尝试以承诺解决问题的原因。任何帮助表示赞赏-谢谢!

1 个答案:

答案 0 :(得分:0)

我的代码理论上可以正常工作。问题,或者至少是我认为的问题是,当我打电话给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(),然后继续进行而没有任何错误。