async и await
В async-функции асинхронные шаги читаются по порядку. await ждёт промис только внутри этой функции; страница и остальной JavaScript продолжают работать.
Что приостанавливает await
На await функция временно возвращает управление браузеру. Другие события могут выполняться. После исполнения промиса функция продолжает с того же места.
async всегда возвращает промис
Даже при возврате строки вызов даёт промис, исполненный этой строкой. Если функция выбрасывает ошибку, промис отклоняется.
Чтение результата после await
pour возвращает промис. serve записывает waiting, ждёт и затем получает lida tea.
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 function serve() {
return "lida tea";
}
let ticket = serve();
console.log(ticket instanceof Promise);
Результат — true: ticket является промисом. Значение читают через await в другой async-функции либо через then.
Обработка отказа через try и catch
Отказ ожидаемого промиса ведёт себя как ошибка в выражении await. Поместите операцию в try.
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-функции. Короткий таймер исполняет промис, поэтому сервер не нужен.
<!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.
🧠 Проверьте Свои Знания
Проверьте Свои Знания
Бросьте себе вызов с помощью этой интерактивной викторины и узнайте, насколько хорошо вы понимаете тему
📝 Инструкции
- Внимательно прочитайте каждый вопрос
- Выберите лучший ответ на каждый вопрос
- Вы можете пересдавать тест столько раз, сколько захотите
- Ваш прогресс будет показан вверху