Приведён JavaScript/Node.js пример с async/await, где промис остается незавершённым из-за забывшегося await — найдите ошибку, объясните konsekvencii и перепишите корректно
Ниже — типичный ошибочный пример и разбор. Ошибочный пример: async function fetchData() { // возвращает промис, который отработает позже return new Promise(resolve => setTimeout(() => resolve('ok'), 1000)); } async function main() { try { fetchData(); // <- забыли await или return console.log('main finished'); } catch (e) { console.error('caught', e); } } main(); Где ошибка - Внутри main вызов fetchData() возвращает Promise, но мы не делаем await и не возвращаем его. main завершится до завершения внутреннего промиса. Последствия (конкретно) - Ошибки из fetchData() не попадут в try/catch в main — они станут необработанными отклонениями (unhandled rejection). - Если вы рассчитываете, что работа завершится до выхода программы, то это не гарантируется: логика продолжит исполнение, возможны гонки и некорректное состояние. - В тестах/скриптах это приведёт к фальшивому успешному завершению или к предупреждениям от Node.js об unhandled rejection. Правильный вариант (await): async function fetchData() { return new Promise(resolve => setTimeout(() => resolve('ok'), 1000)); } async function main() { try { const result = await fetchData(); // Ожидаем завершения console.log('result:', result); } catch (e) { console.error('caught', e); } } main(); Альтернатива — вернуть промис, если main вызывается извне и вызывающая сторона будет ожидать: function main() { return fetchData() .then(result => console.log('result:', result)) .catch(e => console.error('caught', e)); } Или в топ-левеле (если поддерживается) использовать top-level await: const result = await fetchData(); console.log(result); Вывод: либо добавьте await, либо явно return промиса, либо обработайте ошибки через .then/.catch — иначе промис останется асинхронно незавершённым с нежелательными последствиями.
Ошибочный пример:
async function fetchData() {
// возвращает промис, который отработает позже
return new Promise(resolve => setTimeout(() => resolve('ok'), 1000));
}
async function main() {
try {
fetchData(); // <- забыли await или return
console.log('main finished');
} catch (e) {
console.error('caught', e);
}
}
main();
Где ошибка
- Внутри main вызов fetchData() возвращает Promise, но мы не делаем await и не возвращаем его. main завершится до завершения внутреннего промиса.
Последствия (конкретно)
- Ошибки из fetchData() не попадут в try/catch в main — они станут необработанными отклонениями (unhandled rejection).
- Если вы рассчитываете, что работа завершится до выхода программы, то это не гарантируется: логика продолжит исполнение, возможны гонки и некорректное состояние.
- В тестах/скриптах это приведёт к фальшивому успешному завершению или к предупреждениям от Node.js об unhandled rejection.
Правильный вариант (await):
async function fetchData() {
return new Promise(resolve => setTimeout(() => resolve('ok'), 1000));
}
async function main() {
try {
const result = await fetchData(); // Ожидаем завершения
console.log('result:', result);
} catch (e) {
console.error('caught', e);
}
}
main();
Альтернатива — вернуть промис, если main вызывается извне и вызывающая сторона будет ожидать:
function main() {
return fetchData()
.then(result => console.log('result:', result))
.catch(e => console.error('caught', e));
}
Или в топ-левеле (если поддерживается) использовать top-level await:
const result = await fetchData();
console.log(result);
Вывод: либо добавьте await, либо явно return промиса, либо обработайте ошибки через .then/.catch — иначе промис останется асинхронно незавершённым с нежелательными последствиями.