Разница между await и then()
await и .then() — это два способа работы с промисами, но они отличаются по стилю, читаемости и поведению.
Стиль написания кода
С .then() код строится в виде цепочки:
fetchData()
.then(data => processData(data))
.then(result => saveResult(result))
.catch(error => console.error(error));
С await код выглядит как последовательный синхронный:
try {
const data = await fetchData();
const result = processData(data);
await saveResult(result);
} catch (error) {
console.error(error);
}
Второй вариант легче читать, особенно при наличии условий, циклов или нескольких переменных.
Обработка значений
При использовании .then() каждое значение доступно только внутри соответствующего колбэка. Чтобы использовать результат на следующем шаге, нужно возвращать его явно:
fetchUser()
.then(user => {
return fetchPosts(user.id); // без return — undefined
})
.then(posts => console.log(posts));
С await значения сохраняются в обычные переменные и доступны на любом этапе функции:
const user = await fetchUser();
const posts = await fetchPosts(user.id);
console.log(posts);
Обработка ошибок
С .then() ошибку ловит отдельный .catch() в конце цепочки. Если ошибка возникает в любом .then(), она передаётся дальше до .catch().
С await используется стандартный try/catch, что позволяет обрабатывать ошибки точно так же, как в синхронном коде, и даже применять разные блоки catch для разных участков.
Возврат из функции
Функция с .then() требует аккуратного возврата промиса, чтобы результат был доступен снаружи:
function getUserData() {
return fetchUser().then(user => {
return { ...user, loadedAt: Date.now() };
});
}
С async/await возврат происходит естественно:
async function getUserData() {
const user = await fetchUser();
return { ...user, loadedAt: Date.now() };
}
Обе функции возвращают промис, но второй вариант проще понять.
Когда может быть уместен .then()
- При работе с параллельными операциями на верхнем уровне:
Promise.all([a(), b()]).then(([resA, resB]) => { ... }); - В обработчиках событий, где неудобно создавать отдельную
async-функцию:button.addEventListener('click', () => fetchData().then(showData));
Однако даже в этих случаях можно использовать стрелочную async-функцию.
Рекомендация
Используйте async/await по умолчанию. Он делает код линейным, упрощает отладку и совместим со всеми возможностями JavaScript. Резервируйте .then() только для специфических случаев, где он действительно короче или удобнее.