window.speechSynthesis.speak не будет говорить, если никакая другая команда не останется незавершенной

Я пытаюсь написать тестовый код в javascript, где я пытаюсь одновременно регистрировать и произносить случайное число. Для преобразования текста в речь я использую SpeechSynthesisUtterance с window.speechSynthesis:

function generate(){
 for (let i = 0;i<100;i++){
   let randomNumber = numberGenerator.generateNumber();
   showAndSayIt(randomNumber);
 }
}


const showAndSayIt = (m) => {
    var msg = new SpeechSynthesisUtterance(m);
    console.log(m);
    window.speechSynthesis.speak(msg);
}

Когда я запускаю этот код, я сразу получаю все логи и только после того, как все будет готово, я начинаю слышать 100 речей одну за другой. Таким образом, кажется, что все сгенерированные речи накапливаются, а затем, когда нет другой команды для выполнения, генератор речи выдает их все сразу. Есть ли способ изменить это поведение и иметь возможность произносить речь в правильном порядке?

Я пробовал это с Google Chrome 75.


person Mikayil Abdullayev    schedule 03.09.2019    source источник
comment
Пожалуйста, уточните, что вы подразумеваете под правильным порядком. Вы хотите, чтобы это было console.log(1), говорить(1), console.log(2), говорить(2) и т. д.?   -  person Frazer    schedule 03.09.2019
comment
Под the right order я подразумеваю порядок их написания. Да, как вы упомянули console.log(1), затем say(1), затем снова console.log(2) и затем speak(2), где 1 и 2 — случайно сгенерированные числа.   -  person Mikayil Abdullayev    schedule 03.09.2019


Ответы (1)


Ваш анализ верен, что команды говорить запускаются только после завершения всех console.logs. Это связано с тем, что в качестве API методы speechSynthesis (например, speak()) помещаются в очередь задач браузера, чтобы дождаться очистки стека вызовов, т. е. завершения всех console.logs. Вот хорошее видео.

Если вы хотите, чтобы что-то произошло одновременно с чем-то, что попадает в очередь задач, вы можете использовать событие. В этом случае высказывание имеет начало и конец, в зависимости от того, хотите ли вы, чтобы это произошло непосредственно перед или сразу после речи.

Итак, если вы хотите, чтобы console.log отображался непосредственно перед речью, вы можете использовать этот код. Но если вы хотите, чтобы это произошло после изменения onstart на onend.

const showAndSayIt = (m) => {
    const msg = new SpeechSynthesisUtterance(m);
    msg.onstart = () => console.log(m);
    speechSynthesis.speak(msg);
}
person Frazer    schedule 03.09.2019