Управление отменой асинхронной задачи

Я использую Web Speech API для чтения массива слов с небольшой задержкой между каждым (орфографический тест для моего сына!). Я определил асинхронную функцию для произнесения одного слова и использовалsetTimeout()задержать следующее слово на 5 секунд. Все работает как надо, за исключением случаев, когда кнопка СТАРТ нажимается сразу после кнопки СТОП, до того, как 5-секундный тайм-аут разрешится. Это приводит к тому, что весь массив слов начинается снова, а оставшиеся слова из начального теста помещаются между ними. Я попытался исправить это, отменивsetTimeoutметодом и отключением кнопки СТАРТ во время активного тайм-аута, но безуспешно.

1 ответ

Это может показаться немного замысловатым, но вот маршрут отмены, выполненный с помощьюAPI.

Для ясности изложения (и потому, что у меня в браузере нет рабочего синтеза речи) все части, связанные с синтезом речи, были удалены и заменены голымconsole.log, но вы сможете легко вернуть их обратно.

По сути: вместо использования пустой переменной флага каждое «речевое» задание создает новый объект, управляющий своим собственным состоянием отмены, а затем помещает этот объект в глобальную переменную, где его может найти обработчик любой кнопки. Любая кнопка при нажатии отменяет текущее задание, если оно есть; кнопка воспроизведения запустит новую работу. Таким образом, проблема ABA исходного подхода предотвращается.

В этом примере вам может сойти с рук заменачем-то более простым (например, простым предметом сcancelledсвойство), но в общем случае, когда вам нужно вызывать другие веб-API (например,fetch), вам может понадобитьсяAbortControllerв конце концов наготове.

Другие вопросы по тегам