最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to wait until speech is finished inside Loop? - Stack Overflow

programmeradmin1浏览0评论

I would like to halt/wait the for-loop until the window.speechSynthesis.speak(audio) finishes reading the text, then go to next iteration. I have below code:

 var all = "Oak is strong and also gives shade \n \
    Cats and dogs each hate the other \n \
    The pipe began to rust while new \n Bye."


 sentences = all.split('\n')
      for (i = 0; i < sentences.length; i++) {
        sentence = sentences[i]
        console.log(sentences[i]);
        audio = new SpeechSynthesisUtterance(sentence)
        window.speechSynthesis.speak(audio)
         } 

Now what I want is that, once each sentences[i] is printed. The next sentences[i] will not be printed until window.speechSynthesis.speak(audio) is finished, once the speech is finished then the sentences[i] will be printed for the next iteration.

So how can I make the loop wait until a function is not finished?

Note: I can make it wait for a constant time, but I want a dynamic wait, i.e. the wait should be as long aswindow.speechSynthesis.speak(audio) takes time to finish the text.

I would like to halt/wait the for-loop until the window.speechSynthesis.speak(audio) finishes reading the text, then go to next iteration. I have below code:

 var all = "Oak is strong and also gives shade \n \
    Cats and dogs each hate the other \n \
    The pipe began to rust while new \n Bye."


 sentences = all.split('\n')
      for (i = 0; i < sentences.length; i++) {
        sentence = sentences[i]
        console.log(sentences[i]);
        audio = new SpeechSynthesisUtterance(sentence)
        window.speechSynthesis.speak(audio)
         } 

Now what I want is that, once each sentences[i] is printed. The next sentences[i] will not be printed until window.speechSynthesis.speak(audio) is finished, once the speech is finished then the sentences[i] will be printed for the next iteration.

So how can I make the loop wait until a function is not finished?

Note: I can make it wait for a constant time, but I want a dynamic wait, i.e. the wait should be as long aswindow.speechSynthesis.speak(audio) takes time to finish the text.

Share Improve this question edited Sep 22, 2019 at 14:47 norbitrial 15.2k10 gold badges38 silver badges64 bronze badges asked Sep 22, 2019 at 13:03 Consider Non-Trivial CasesConsider Non-Trivial Cases 692 silver badges12 bronze badges 1
  • 1 Hello and welcome! Take a look at developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/… – pep 1 Commented Sep 22, 2019 at 13:07
Add a comment  | 

2 Answers 2

Reset to default 16

For SpeechSynthesisUtterance API there is an onend event what you can play with (SpeechSynthesisUtterance: end event).

So I guess you can add an event listener to onend where you need to call the next iteration's code. One good technique is to use Promise in asynchronous cases to wait until a callback finishes. I have created a working example for the above case from your question:

(function() {
  play();

  async function play() {
    let all = "Oak is strong and also gives shade \n \
              Cats and dogs each hate the other \n \
              The pipe began to rust while new \n Bye.";

    sentences = all.split('\n');

    for (i = 0; i < sentences.length; i++) {
      await getNextAudio(sentences[i]);
    }

    async function getNextAudio(sentence) {
      console.log(sentence);
      let audio = new SpeechSynthesisUtterance(sentence);
      window.speechSynthesis.speak(audio);

      return new Promise(resolve => {
        audio.onend = resolve;
      });
    } 
  }
})();

If you are interested in more details, please go for the following links to read further:

  1. Promise
  2. SpeechSynthesis.speak()
  3. SpeechSynthesisUtterance.onend
  4. async function

The solution works just like charm, hope this helps!

There's also an onstart event which you could use like this:

for (i = 0; i < sentences.length; i++) {
  const sentence = sentences[i];
  const audio = new SpeechSynthesisUtterance(sentence);
  audio.onstart = () => console.log(audio.text);
  speechSynthesis.speak(audio);
}

Or slightly shorter:

for (const sentence of sentences) {
  const audio = new SpeechSynthesisUtterance(sentence);
  audio.onstart = () => console.log(audio.text);
  speechSynthesis.speak(audio);
}

PS you could amend the top of your code to use const (or let) instead of var like this:

const all = "Oak is strong and also gives shade \n \
    Cats and dogs each hate the other \n \
    The pipe began to rust while new \n Bye.";
const sentences = all.split('\n');
发布评论

评论列表(0)

  1. 暂无评论