SpeechRecognition: цикл через набор вопросов; ожидание каждого «устного» ответа, прежде чем задавать следующий вопрос - PullRequest
0 голосов
/ 07 апреля 2019

У меня есть анкета из 6 вопросов.Они представлены через синтез речи.После каждого вопроса мне нужно дождаться устного ответа, который я обработаю, прежде чем представить следующий вопрос.Мой код это попытка.Код проходит через обратный вызов.Но как последовательно обрабатывать логику: «сформулировать вопрос», «прослушать», «сформулировать следующий вопрос», «прослушать» ...


//..ToDo: Because we need verbal response for each question,
//..   we need to change the recognition.onResult call back

function processPromptedInteraction(event)
{
    var speechToText = event.results[0][0].transcript;
    if (speechToText.includes('yes'))
    {    }
    else if (speechToText.includes('no'))
    {    }
    else
    {    }
}

var strQuestion = '';
for (i = 0; i < questions[i].length; i++) 
{
    recognition.onresult = processPromptedInteraction; //.. Callback function
    strQuestion = questions[i].question;
    say(strQuestion);
}

1 Ответ

0 голосов
/ 07 апреля 2019

events являются асинхронными, поэтому ваш код не ждет, когда пользователи ответят на вопросы один за другим. Надеюсь, что следующее решение работает для вас. Дайте мне знать, если я что-то упустил.

Примечание: Код может не работать здесь из-за безопасности браузера. Используйте ссылку jsfiddle ниже для запуска кода. Смотрите консоль браузера для окончательного результата

https://jsfiddle.net/ajai/L8p4aqtr/

class Questions {
  constructor(questions) {
    this.questions = questions;
    this.currentIndex = 0;
    this.MAX = this.questions.length - 1;

    // answers hash
    this.answers = questions.reduce((hash, q) => {
      hash[q] = '';
      return hash;
    }, {});

    this.initSpeech();
  }

  initSpeech() {
    const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;

    this.speechSynthesis = window.speechSynthesis;

    this.recognition = new webkitSpeechRecognition();

    this.recognition.continuous = true;
    this.recognition.interimResults = false;

    this.recognition.onresult = this.recognize.bind(this);
  }

  recognize(event) {
    const last = event.results.length - 1;
    const result = event.results[last][0].transcript;

    if (result.includes('yes')) {
      this.setAnswer('Yes');
      this.next();
    } else if (result.includes('no')) {
      this.setAnswer('No');
      this.next();
    } else {
      // ask same question again
      this.say('Can\'t recognize your answer');
      this.ask();
    }
  }

  setAnswer(answer) {
    this.answers[this.questions[this.currentIndex]] = answer;
  }

  start() {
    this.currentIndex = 0;
    this.recognition.start();

    this.ask();

    return this;
  }

  stop() {
    this.recognition.stop();

    this.onComplete && this.onComplete(this.answers);
  }

  ask() {
    const questionToAsk = this.questions[this.currentIndex];
    this.say(questionToAsk);
  }

  say(msg) {
    const synth = new SpeechSynthesisUtterance(msg);
    this.speechSynthesis.speak(synth);
  }

  next() {
    if (this.currentIndex < this.MAX) {
      this.currentIndex++;
      this.ask();
    } else {
      this.stop();
    }
  }

  getAnswers() {
    return this.answers;
  }

  static create(questions) {
    return new Questions(questions);
  }
}

// const q = new Questions(['Question 1?', 'Question 2?', 'Question 3?']);
const q = Questions.create(['Question 1?', 'Question 2?', 'Question 3?']);

q.start().onComplete = function(result) {
  console.log(this.answers);
};
...