如何使用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循环中真正快速地循环。任何想法将不胜感激。
答案 0 :(得分:0)
首先,say
需要返回一个Promise
,该会话一旦完成就可以解决。这样,您可以在say()
循环内调用await
和for
。当前,您正在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
)声明新变量,以免隐式分配给窗口属性。