Управление отменой асинхронной задачи
Я использую Web Speech API для чтения массива слов с небольшой задержкой между каждым (орфографический тест для моего сына!). Я определил асинхронную функцию для произнесения одного слова и использовалsetTimeout()
задержать следующее слово на 5 секунд. Все работает как надо, за исключением случаев, когда кнопка СТАРТ нажимается сразу после кнопки СТОП, до того, как 5-секундный тайм-аут разрешится. Это приводит к тому, что весь массив слов начинается снова, а оставшиеся слова из начального теста помещаются между ними. Я попытался исправить это, отменивsetTimeout
методом и отключением кнопки СТАРТ во время активного тайм-аута, но безуспешно.
1 ответ
Это может показаться немного замысловатым, но вот маршрут отмены, выполненный с помощьюAPI.
Для ясности изложения (и потому, что у меня в браузере нет рабочего синтеза речи) все части, связанные с синтезом речи, были удалены и заменены голымconsole.log
, но вы сможете легко вернуть их обратно.
По сути: вместо использования пустой переменной флага каждое «речевое» задание создает новый объект, управляющий своим собственным состоянием отмены, а затем помещает этот объект в глобальную переменную, где его может найти обработчик любой кнопки. Любая кнопка при нажатии отменяет текущее задание, если оно есть; кнопка воспроизведения запустит новую работу. Таким образом, проблема ABA исходного подхода предотвращается.
В этом примере вам может сойти с рук заменачем-то более простым (например, простым предметом сcancelled
свойство), но в общем случае, когда вам нужно вызывать другие веб-API (например,fetch
), вам может понадобитьсяAbortController
в конце концов наготове.