如何等到 Loop 内的语音完成?

Con*_*ses 7 javascript text-to-speech wait

我想暂停/等待 for 循环,直到window.speechSynthesis.speak(audio)完成阅读文本,然后再进行下一次迭代。我有以下代码:

 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)
         } 
Run Code Online (Sandbox Code Playgroud)

现在我想要的是,每个sentences[i]打印一次。在完成sentences[i]之前不会打印 下一个window.speechSynthesis.speak(audio),一旦语音完成,sentences[i] 则将打印下一次迭代。

那么我怎样才能让循环等到一个函数没有完成呢?

注意:我可以让它等待一个恒定的时间,但我想要一个动态的等待,即等待时间应该window.speechSynthesis.speak(audio)与完成文本所需的时间一样长。

nor*_*ial 11

对于SpeechSynthesisUtteranceAPI,onend您可以使用一个事件(SpeechSynthesisUtterance: end event)。

所以我想你可以onend在需要调用下一次迭代代码的地方添加一个事件监听器。一种好的技术是Promise在异步情况下使用等待回调完成。我根据您的问题为上述案例创建了一个工作示例:

(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;
      });
    } 
  }
})();
Run Code Online (Sandbox Code Playgroud)

如果您对更多详细信息感兴趣,请访问以下链接以进一步阅读:

  1. 承诺
  2. SpeechSynthesis.speak()
  3. SpeechSynthesisUtterance.onend
  4. 异步函数

该解决方案就像魅力一样,希望这会有所帮助!