Неожиданное и различное поведение одной и той же функции при ее выполнении с помощью setTimeout или кнопки - PullRequest
0 голосов
/ 25 января 2020

В моем коде запутанная и запутанная проблема.

Я только что написал простой код распознавания речи с использованием веб-речевого API, он отлично работает.

При каждом запуске распознавания я создаю и запускаю таймер для остановки и завершения распознавания через 14 секунд, например:

recognition.onstart = function(event) {
        //Fired when the speech recognition service has begun listening
        console.log('SpeechRecognition.onstart');

        // start timer at first recognaze firing 
        if(firstTime === true){

           console.log('Entered firstTime block ')  

           timer = setInterval(stopwatch, 500);
           firstTime = false;

           function stopwatch() {

              secs += 0.5;
              console.log(secs);

              if(secs >= 14){

              clearInterval(timer);
              speaking = false;
              recognition.stop();
              console.log("Timer has stoped!");

            }
          }
        }   
}

Как видите, я очищаю интервал и останавливаю распознавание через 14 секунд.

Теперь Что, если я хочу сделать то же самое, когда пользователь нажимает клавишу пробел на клавиатуре? возможно, я смогу выполнить точные строки очистки и остановки распознавания следующим образом:

   window.onkeypress = function(event) {

       if (event.keyCode == 32) {

           console.log("User pressed Space Key");  

           clearInterval(timer);
           speaking = false;
           recognition.stop();
           console.log("So this should be another way to end the whole thing!");       

       }

    };

На этот раз это не сработает, как ожидалось!

давайте кратко рассмотрим код: (я скажу, что за запутанная проблема через секунду)

JS

// Using a button to initiate the Recognize() crashes the code
function onclicked() {
  Recognize();
 }

// But if we use a timeout to initiate Recognize() instead of clicking the button the code works fine 
// console.log('started')
// setTimeout(function(){
//    Recognize();


// }, 4000)



function Recognize() {

    var SpeechRecognition = SpeechRecognition || webkitSpeechRecognition;
    var SpeechGrammarList = SpeechGrammarList || webkitSpeechGrammarList;
    var SpeechRecognitionEvent = SpeechRecognitionEvent || webkitSpeechRecognitionEvent;

    let secs = 0;
    let speaking = true;
    let firstTime = true;
    let timer;

    var recognition = new SpeechRecognition();
    var speechRecognitionList = new SpeechGrammarList();
    recognition.grammars = speechRecognitionList;
    recognition.lang = 'en-US';
    recognition.continuous = true;
    recognition.interimResults = true;
    recognition.maxAlternatives = 1;

    recognition.start();

    window.onkeypress = function(event) {

       if (event.keyCode == 32) {

           console.log("User pressed Space Key");  

           clearInterval(timer);
           speaking = false;
           recognition.stop();
           console.log("So this should be another way to end the whole thing!");       

       }

    };



    recognition.onresult = function(event) {

        window.interim_transcript = '';
        window.speechResult = '';

        for (var i = event.resultIndex; i < event.results.length; ++i) {
            // Verify if the recognized text is the last with the isFinal property
            if (event.results[i].isFinal) {              

                speechResult += event.results[i][0].transcript;
                console.log("Final Recognized Speech: ", speechResult);
                recognition.stop();

            } else {

                interim_transcript += event.results[i][0].transcript;

            }
        }

    }


    recognition.onspeechend = function() {
        recognition.stop();
        console.log('Speech ended!');
    }

    recognition.onend = function(event) {
        //Fired when the speech recognition service has disconnected. 

        console.log('onend executed...');

        if(typeof speechResult !== 'undefined'){

          console.log('User has spoken something..')

          clearInterval(timer);

        } else {

            if(speaking === true) {

               console.log('No speech detected but still we have time, so give user another chance..')
               recognition.start();

            } else {

              //User was silent and the time has finished so he is incorrect
              console.log('No speech detected and no time, we failed..')

            }


      }     

  };      



recognition.onstart = function(event) {
        //Fired when the speech recognition service has begun listening
        console.log('SpeechRecognition.onstart');

        // start timer at first recognaze firing 
        if(firstTime === true){

           console.log('Entered firstTime block ')  

           timer = setInterval(stopwatch, 500);
           firstTime = false;

           function stopwatch() {

              secs += 0.5;
              console.log(secs);

              if(secs >= 14){

              clearInterval(timer);
              speaking = false;
              recognition.stop();
              console.log("Timer has stoped!");

            }
          }
        }   
}

};

HTML

<!DOCTYPE html>
<html>
<body>
<button onclick="onclicked()">Click me</button>
</body>
</html>

Использование кнопки для запуска Recognize() приводит к сбою кода, но использование тайм-аута для запуска Recognize() вместо нажатия кнопки работает должным образом !

Пожалуйста, используйте CodePen для проверки этого: https://codepen.io/pixy-dixy/pen/rNaRmOX?editors=0010

Почему происходит такое неожиданное поведение? Я что-то пропустил? Пожалуйста, помогите, я так запутался: (

ОБНОВЛЕНИЕ: Кажется, что код работает хорошо в обоих сценариях ios, только если я нажимаю на пустую часть страницы (Не кнопка ) перед нажатием пробела!

...