Обещание не разрешается после setTimeOut - PullRequest
4 голосов
/ 03 июня 2019

Я использую плагин для распознавания речи Cordova, где после нажатия пользователем кнопки речи срабатывает startRecognition, но если после 10000 мс, если пользователь ничего не говорит, то должна запускаться функция stopListening(), и она будет работать непрерывно, пока пользовательговорит выход.

Я использую setTimeout, завернутый в обещание, и когда это обещание разрешается, я решаю обещание, которое запускает плагин cordova для распознавания речи

Этот код будет постояннозапускать распознавание речи, если пользователь не говорит выход.

  listenMsgAndReplyRepeat() {
    const self = this;
    this.listenMsg().then(res => {
      alert('got result ' + res);
      if (res === 'Exit') {
        self.exitFromApp();
      } else if (res === 'Success') {
        self.listenMsgAndReplyRepeat();
      } else if (res === 'Stopped') {
        alert('the speech recognition was stopped');
        self.botReply('Hello? Do you Want me to Exit?');
        self.listenMsgAndReplyRepeat();
      } else {
        self.botReply('Some error occured will detecting speech');
      }
    });
  }

Этот код запускает распознавание речи

listenMsg() {
    const self = this;
    // Verify if recognition is available
    return new Promise(function(resolve, reject) {
      self
        .isRecognitionAvailable()
        .then(function(available) {
          if (available) {
            return window.plugins.speechRecognition.hasPermission();
          }
        })
        .then(function(hasPermission) {
          function startRecognition() {
            self.speakPopUp = true;
            return self
              .startRecognition({
                language: 'en-US',
                showPopup: false,
                matches: 2
                // showPartial: true
              })
              .then(function(result) {
                clearTimeout(self.stopListen);
                self.speakPopUp = false;
                if (result[0] === 'exit') {
                    resolve('Exit'); //working
                }
                self.botReply(result[0]).then(res => {
                  resolve('Success'); //working
                });
              })
              .catch(function(err) {
                reject('Error');
              });
          }
          if (!hasPermission) {
            self
              .requestPermission()
              .then(function() {
                self.stopSpeech().then(res => {
                  self.speakPopUp = false;
                  resolve('Stopped');  //this resolve is not working
                });
                startRecognition();
              })
              .catch(function(err) {
                console.error('Cannot get permission', err);
                reject('Error');
              });
          } else {
            self.stopSpeech().then(res => {
              self.speakPopUp = false;
              resolve('Stopped');  //this resolve is not working
            });
            startRecognition();
          }
        })
        .catch(function(err) {
          console.error(err);
          reject('Error');
        });
    });
  }

Разрешение внутри локальной функции startRecognition работает, но внутриесли условие не работает

Вот код stopRecognition

  stopSpeech() {
    const self = this;
    return new Promise(function(resolve, reject) {
      self.stopListen = setTimeout(() => {
        self.stopListening().then(res => {
          clearTimeout(self.stopListen);
          resolve('stopped');
        });
      }, 10000);
    });
  }

Разрешение внутри setTimeOut работает.

Я назначаю setTimeOutпеременной, потому что, если пользователь говорит, я должен очистить ее, чтобы stopListening не сработало.

1 Ответ

0 голосов
/ 04 июня 2019

Мне удалось решить эту проблему с помощью Promise.all (). Я обернул тайм-аут внутри обещания и передал его в массив обещаний, после чего выдвинул ему обещание stopListening.

const promises = [];
promises.push(self.delay(10000));
promises.push(self.stopListening());
Promise.all(promises).then((res) => {
   self.speakPopUp = false;
   resolve('Stopped');
  });
  delay(t) {
    return new Promise(function(resolve) {
        setTimeout(resolve, t);
    });
...