带有SpeechSynthesis.speak()的javascript中的同步执行

时间:2018-12-01 17:59:40

标签: javascript html5 text-to-speech

当前,我正在尝试让浏览器按顺序说出一个字符串数组,但这不是按顺序进行的;读取第一个字符串,然后读取最后一个字符串。如何修改代码,以便依次读取每个字符串?

async function wrapper(){
  var text = "sen ten ce one. sen ten ce two. sen ten ce three.";
  var result = text.match( /[^\.!\?]+[\.!\?]+/g );
  var ssu = new SpeechSynthesisUtterance();
  for(var i = 0; i<result.length; i++){
    sentence = result[i];
    ssu.text = sentence;
    await window.speechSynthesis.speak(ssu);
  }
wrapper();

如果我将句子写到控制台,则会在说出句子之前将它们打印出来。

2 个答案:

答案 0 :(得分:2)

您不能将awaitspeechSynthesis.speak()一起使用,因为它不会返回承诺。您可以通过使用onend事件并将其包装在Promise中来解决此问题:

async function wrapper(){
  var text = "sen ten ce one. sen ten ce two. sen ten ce three.";
  var result = text.match( /[^\.!\?]+[\.!\?]+/g );
  var ssu = new SpeechSynthesisUtterance();
  for(var i = 0; i<result.length; i++){
    sentence = result[i];
    ssu.text = sentence;
    await new Promise(function(resolve) {
      ssu.onend = resolve;
      window.speechSynthesis.speak(ssu);
    });
  }
wrapper();

答案 1 :(得分:1)

async await仅与promise一起使用。 speachSynthesis.speak不会返回承诺,因此不会等到语音完成。因此,最好使用onend回调。

检查以下代码

var ssu = new SpeechSynthesisUtterance();

function wrapper(){
  var text = "sen ten ce one. sen ten ce two. sen ten ce three. sen ten ce four.";
  var result = text.match( /[^\.!\?]+[\.!\?]+/g );

  speak(result, 0);
}

function speak(result, index) {
    if(index >= result.length)
        return;

    var sentence = result[index];
    ssu.text = sentence;
    ssu.onend = function() {
        speak(result, ++index);
    };
    window.speechSynthesis.speak(ssu);
}

wrapper()