Этот вопрос проверяет знание эволюции асинхронного программирования в JavaScript и понимание современных подходов, таких как async/await.
После широкого внедрения Promise в JavaScript (ES2015) следующим логическим шагом в развитии асинхронного программирования стало появление синтаксиса async/await, который был стандартизирован в ES2017 (ES8). Этот подход построен поверх Promise и не заменяет их, а предоставляет более удобный и читаемый способ работы с асинхронными операциями.
Ключевое слово async, поставленное перед объявлением функции, указывает, что эта функция всегда возвращает Promise. Если функция возвращает не-Promise значение, оно автоматически оборачивается в разрешённый Promise. Внутри такой функции можно использовать ключевое слово await. Оно приостанавливает выполнение функции до тех пор, пока Promise, перед которым оно стоит, не будет разрешён (fulfilled) или отклонён (rejected). При этом поток выполнения не блокируется — управление возвращается в событийный цикл.
Сравним код с Promise и с async/await для последовательного выполнения двух асинхронных операций (например, загрузки данных пользователя, а затем его постов).
// Старый стиль с Promise и .then()
function getUserAndPosts(userId) {
return fetchUser(userId)
.then(user => {
return fetchPosts(user.id);
})
.then(posts => {
console.log('Posts:', posts);
return posts;
})
.catch(error => {
console.error('Error:', error);
});
}
// Новый стиль с async/await
async function getUserAndPostsAsync(userId) {
try {
const user = await fetchUser(userId);
const posts = await fetchPosts(user.id);
console.log('Posts:', posts);
return posts;
} catch (error) {
console.error('Error:', error);
}
}
// Предполагаемые функции-заглушки, возвращающие Promise
function fetchUser(id) { return Promise.resolve({ id, name: 'John' }); }
function fetchPosts(userId) { return Promise.resolve(['Post1', 'Post2']); }Async/await стал стандартом де-факто для написания асинхронного кода в современных JavaScript-приложениях, особенно в Node.js серверах и фронтенд-фреймворках (React, Vue, Angular). Он идеально подходит для:
try/catch.Важно помнить, что await можно использовать только внутри async-функций. На верхнем уровне модулей в современных средах также поддерживается await.
Вывод: Используйте async/await, когда вам нужен чистый, линейный и легко читаемый код для работы с асинхронными операциями, особенно при наличии последовательных зависимостей или сложной логики обработки ошибок. Это основной инструмент в арсенале современного JavaScript-разработчика.