Why does a SpeechSynthesisUtterance sometimes not fire an 'end' event in Chromium-based browsers?

隐身守侯 提交于 2019-12-03 09:54:51

Edit/Update: @Ouroborus pointed out that this is indeed an open Chromium bug


I fired up Sawbuck and started attempts to reproduce this. When the issue occurs, I consistently see gc activity happening between the 'start script' and 'finished?' logs.

Example of success:

Example of failure:

So, it seems like it may be that the gc process is interfering with the end event being delivered.

To further test this theory I started chrome with the --js-flags="--expose-gc" flag which enables the v8 gc function, allowing one to force garbage collection.

If I modify your test code and add window.gc() before console.log('start script'), I can no longer reproduce the issue (>50 attempts). It's possible this is because it reduces/eliminates the chance that gc occurs during the speech utterance.

It seems that you may be able to prevent the SpeechSynthesisUtterance object from being gc'd by console.log-ing it. This does seem to result in consistent delivery of the event. Obviously preventing their collection is probably not ideal if you're creating a great number of these objects:

button.onclick = () => {
  console.log('start script');
  button.disabled = true;
  const utt = new SpeechSynthesisUtterance('e');
  
  // Prevent garbage collection of utt object
  console.log(utt);

  utt.addEventListener('end', () => {
    console.log('end event triggered');
  });

  // just for debugging completeness, no errors seem to be thrown though
  utt.addEventListener('error', (err) => {
    console.log('err', err)
  });

  speechSynthesis.speak(utt);
  setTimeout(() => {
    console.log('finished?');
  }, 1500);
};
<button id="button">click</button>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!