Одно за другим
Функция, помеченная async, может ждать несколько раз. Каждый await ждёт свой промис, и только после этого функция переходит к следующей строке. Так легко описывать то, что происходит одно за другим, как в рецепте.
Для самого ожидания есть удобная короткая функция, которую вы найдёте в script.js этого упражнения:
function wait(ms) {
return new Promise(function (resolve) {
setTimeout(resolve, ms);
});
}Она возвращает промис, который получает значение, когда проходит ms миллисекунд: setTimeout() вызывает для него resolve. Поэтому await wait(1000); приостанавливает async-функцию на секунду. Сравните отсчёт для ракеты через setInterval() с таким:
launchButton.addEventListener("click", async function () {
for (let seconds = 3; seconds > 0; seconds--) {
countdown.textContent = seconds;
await wait(1000);
}
countdown.textContent = "Взлёт!";
});Цикл показывает 3 и ждёт секунду, показывает 2 и ждёт, показывает 1 и ждёт, а затем ракета взлетает. Останавливать нечего: цикл просто заканчивается.
Без await каждый следующий шаг пришлось бы помещать в функцию таймера внутри функции предыдущего таймера, и с каждым шагом код разрастался бы вправо.
Типичная ошибка — забыть await перед wait(1000): тогда никто не ждёт, и все шаги происходят сразу. Вы видите только последний.
В следующем уроке вы будете вот так же ждать дважды подряд: сначала ответа сервера, потом данных в нём.
Задание
- 1
Когда нажата
pressButton, покажите оранжевоеЖдите…черезshowLight("Ждите…", "orange"), подождите секунду, а затем покажите зелёноеИдите. Не забудьте написатьasyncпередfunctionобработчика. - 2
Зелёный свет тоже горит всего секунду: ещё через секунду снова покажите красное
Стойте. - 3
Нажмите кнопку ещё раз, пока свет меняется, и шаги перепутаются: теперь одновременно работают два обработчика. Отключите
pressButtonв начале обработчика и включите снова в конце, после того как свет станет красным.