Промисы — очень удобный инструмент организации асинхронного кода. Но мозгу человека намного привычнее синхронные операции. Сделали что-то, подождали, потом продолжили.
Await
Для упрощения асинхронных операций в JavaScript придумали ключевое слово await
. Если написать его перед функцией, которая возвращает промис, то выполнение программы остановится до тех пор, пока промис не завершится.
const userCount = await getUserCount();
console.log(userCount); // 12345
На экране появится сразу значение с которым завершится промис, который возвращает getUserCount()
. А если не написать await
, то мы увидим в консоли строку Promise { <pending> }
.
Async
Ключевое слово await
нельзя использовать в обычной функции. Нужно обязательно сделать ее асинхронной, добавив перед списком параметров функции ключевое слово async
.
const logUserCount = async () => {
const userCount = await getUserCount();
console.log(userCount);
}
Все асинхронные функции возвращают Promise
, даже если внутри них нет await
.
const getHelloWorld = async () => {
return 'Hello, world!';
}
console.log(getHelloWorld); // Promise { <pending> }
А чтобы получить результат промиса, нужно добавить все тот же await
. Или убрать async
, если ты точно уверен, что функция getHelloWorld
будет выполнять только синхронные операции.
const getHelloWorld = async () => {
return 'Hello, world!';
}
console.log(await getHelloWorld()); // Hello, world!
Обработка ошибок
Ошибка может возникнуть всегда. Особенно в асинхронных операциях. Файл может оказаться недоступен, когда мы пытаемся его прочитать. Или может пропасть интернет, когда мы будет грузить картинку с удаленного сервера.
Ошибки в промисах обрабатываются с помощью .catch()
:
fetchUserData(userId).then(console.log).catch(handleError);
Но если ты используешь await
для ожидания промиса, то ты можешь использовать для обработки ошибок обычный блок try/catch
:
try {
await fetchUserData(userId)
} catch (e) {
console.log('asynchronous error was caught!');
handleError(e);
}