简体   繁体   English

如何遍历Web Speech API中的问题

[英]How to loop over questions in Web Speech API

How can I loop over a list of questions with Web Speech API. 如何使用Web Speech API遍历问题列表。 For example I want to ask a series of Yes or No questions and then handle the result differently if the answer is yes, and move on to the next question if the answer is no. 例如,我想问一系列“是”或“否”问题,然后如果答案为“是”,则以不同的方式处理结果,如果答案为“否”,则转到下一个问题。

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

The issue is that it never will call listenToAnswer() and listen to the next user input. 问题在于,它永远不会调用listenToAnswer()并监听下一个用户输入。 Instead it just loops really quickly through the the for loop of questions. 相反,它只是在问题的for循环中真正快速地循环。 Any thoughts would be greatly appreciated. 任何想法将不胜感激。

First, say needs to return a Promise that resolves once the speaking is done. 首先, say需要返回一个演讲结束Promise解决的Promise That way, you can call say() and await it inside the for loop. 这样,您可以调用say()并在for循环中await它。 Currently, you're constructing a Promise inside pickQuestion , but then you're resolving it immediately because you're calling its resolve right after the Promise is constructed. 当前,您正在pickQuestion内部构造一个Promise ,但是随后您要立即解决它因为在Promise构造后立即调用了它的resolve So, there's no time for anything asynchronous to be done. 因此,没有时间进行任何异步操作了。

Once say returns a Promise , you can avoid constructing another Promise inside the for loop, and simply await the say call: 一旦say返回Promise ,您就可以避免在for循环内构造另一个Promise ,而只需等待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;
    }
  }
}

Make sure to declare new variables with const (or let ) so as not to implicitly assign to window properties. 确保使用const (或let )声明新变量,以免隐式分配给窗口属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM