Загрузка...

async и await

В async-функции асинхронные шаги читаются по порядку. await ждёт промис только внутри этой функции; страница и остальной JavaScript продолжают работать.

Что приостанавливает await

На await функция временно возвращает управление браузеру. Другие события могут выполняться. После исполнения промиса функция продолжает с того же места.

async всегда возвращает промис

Даже при возврате строки вызов даёт промис, исполненный этой строкой. Если функция выбрасывает ошибку, промис отклоняется.

Чтение результата после await

pour возвращает промис. serve записывает waiting, ждёт и затем получает lida tea.

Await внутри serve

javascript
function pour(order) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
if (order === "") reject("no leaves");
else resolve(order + " tea");
}, 100);
});
}
async function serve() {
console.log("waiting");
let drink = await pour("lida");
console.log(drink);
}
serve();

Сначала выводится waiting, затем lida tea. Обе строки находятся в serve, но вторая выполняется после промиса.

Вызывающий код получает промис

serve() без await не возвращает напиток напрямую.

Async-вызов возвращает промис

javascript
async function serve() {
return "lida tea";
}
let ticket = serve();
console.log(ticket instanceof Promise);

Результат — true: ticket является промисом. Значение читают через await в другой async-функции либо через then.

Обработка отказа через try и catch

Отказ ожидаемого промиса ведёт себя как ошибка в выражении await. Поместите операцию в try.

Перехват ожидаемого отказа

javascript
function pour(order) {
return order === ""
? Promise.reject("no leaves")
: Promise.resolve(order + " tea");
}
async function serveEmpty() {
try {
await pour("");
} catch (reason) {
console.log(reason);
}
}
serveEmpty();

Выводится no leaves. Другие ошибки в том же блоке try также попадут в этот catch.

Остальная страница продолжает работу

Приостанавливается только текущая async-функция. Её вызов сразу возвращает промис, и следующий синхронный код выполняется.

Полный пример в браузере

Пример записывает этапы в одной async-функции. Короткий таймер исполняет промис, поэтому сервер не нужен.

Полная async-страница

html
<!DOCTYPE html>
<html>
<body>
<p id="cup">blank</p>
<p id="line">…</p>
<script>
function pour(order) {
return new Promise(resolve => setTimeout(() => resolve(order + " tea"), 100));
}
async function serve() {
const cup = document.getElementById("cup");
const seen = ["waiting"];
cup.textContent = "waiting";
const drink = await pour("lida");
cup.textContent = drink;
seen.push(drink, "done");
document.getElementById("line").textContent = seen.join(" / ");
}
serve();
</script>
</body>
</html>

Итоговая строка: waiting / lida tea / done. Слово done добавляется после ожидаемого значения.

Попробуйте

Измените lida и дождитесь результата. Затем передайте пустую строку и убедитесь, что catch получает no leaves.

Частые ошибки

Не ждите готовую строку от async-вызова. Не используйте await в обычной функции и не считайте, что он останавливает всю страницу.

Запомните

async всегда возвращает промис. await приостанавливает лишь эту функцию до завершения промиса. Для отказа применяйте try/catch.

🧠 Проверьте Свои Знания

Готов к Началу

Проверьте Свои Знания

Бросьте себе вызов с помощью этой интерактивной викторины и узнайте, насколько хорошо вы понимаете тему

❓
6
Вопросы
🎯
70%
Для Прохождения
♾️
∞
Время
🔄
∞
Попытки

📝 Инструкции

  • Внимательно прочитайте каждый вопрос
  • Выберите лучший ответ на каждый вопрос
  • Вы можете пересдавать тест столько раз, сколько захотите
  • Ваш прогресс будет показан вверху