如何遍历Web Speech API中的问题

时间:2018-08-26 18:02:46

标签: javascript webspeech-api

如何使用Web Speech API遍历问题列表。例如,我想问一系列“是”或“否”问题,然后如果答案为“是”,则以不同的方式处理结果,如果答案为“否”,则转到下一个问题。

var questions = //array of five questions
function answerQuestions {
    for (i = 0; questions.length; i++) {
      if (askUser(questions[i]) {
          ///Do something if yes
      } else if ((i+1) === questions.length){
         //stop asking questions
      }
}
function askUser (question) {
    //instantiate Web Speech API
     //someinstance.speak(question)
 }
function say(m){   
    var msg = new SpeechSynthesisUtterance();   
    var voices = window.speechSynthesis.getVoices();    
    msg.voice = voices[10];     
    msg.voiceURI = "Google UK English Male";    
    msg.volume = 1;     
    msg.rate = 1;   
    msg.pitch = 1.4;    
    msg.text = m;   
    msg.lang = 'en-GB';     
    speechSynthesis.speak(msg); 
    msg.onend = function () {
        listenToAnswer()
    }
}

问题在于它永远不会调用listenToAnswer()并监听下一个用户输入。相反,它只是在问题的for循环中真正快速地循环。任何想法将不胜感激。

1 个答案:

答案 0 :(得分:0)

首先,say需要返回一个Promise,该会话一旦完成就可以解决。这样,您可以在say()循环内调用awaitfor。当前,您正在Promise内构造一个pickQuestion,但是您要立即解决它,因为您在Promise完成后立即调用了resolve建造。因此,没有时间进行任何异步操作了。

一旦say返回一个Promise,您就可以避免在Promise循环内构造另一个for,而只需等待say调用:

function say(m){
  return new Promise((resolve) => {
    const msg = new SpeechSynthesisUtterance();   
    var voices = window.speechSynthesis.getVoices();    
    msg.voice = voices[10];     
    msg.voiceURI = "Google UK English Male";    
    msg.volume = 1;     
    msg.rate = 1;   
    msg.pitch = 1.4;    
    msg.text = m;   
    msg.lang = 'en-GB';     
    speechSynthesis.speak(msg); 
    msg.onend = function () {
      resolve()
    }
  });
}

async function pickQuestion(subject) {
  const questionsOfSubject = questions[subject];
  for (let i = 0; i < questionsOfSubject.length; i++) {
    await say("Would you like to read, " + questionsOfSubject[i].title);
    const answer = await listenToResponse();
    if (answer.toLowerCase() === "yes") {
      readQuestion();
      break;
    }
  }
}

确保使用const(或let)声明新变量,以免隐式分配给窗口属性。