Разберите JavaScript-фрагмент: async function fetchData(){ try{ let res = fetch(url); let data = await res.json(); }catch(e){console.log(e);} } — объясните ошибку в работе с промисами и как её исправить; какие ещё распространённые ошибки при работе с async/await вы знаете?
Ошибка в фрагменте — вы не дождались результата `fetch`. В коде let res = fetch(url); res становится Promise, а не объектом Response, поэтому вызов `res.json()` даёт ошибку (TypeError: res.json is not a function). Как исправить (минимально): async function fetchData(){ try{ const res = await fetch(url); // ← await здесь const data = await res.json(); return data; }catch(e){ console.log(e); throw e; // по необходимости пробросить } } Рекомендации по надёжности: - Проверять HTTP-статус: `if (!res.ok) throw new Error(\`HTTP \${res.status}\`);` — fetch отклоняет промис только при сетевой ошибке, 4xx/5xx не считаются rejected. - Обрабатывать возможную ошибку парсинга JSON в отдельном try/catch, если нужно различать ошибки. - Использовать AbortController для отмены длительных запросов и предотвращения утечек. Распространённые ошибки при работе с async/await (кратко и как исправлять): - Забыл `await` перед промисом (как в примере) → получаешь промис вместо значения; добавить `await` или использовать `.then`. - Ожидание внутри `try` без `await`: `try { someAsync(); } catch(e) {}` — catch не поймает ошибку. Нужно `await someAsync();`. - Использование `Array.prototype.forEach` с `async`-колбэком — `forEach` не ждёт промисы. Используйте `for...of`, `Promise.all(...)` или `map`+`Promise.all`. - Слишком последовательное выполнение там, где можно параллелить: делать `await` в цикле вызывает серию запросов последовательно; для параллели соберите промисы и `await Promise.all(promises)`. - Поглощение ошибок (пустой catch или только логирование) — теряются ошибки; по необходимости пробрасывайте дальше или корректно обрабатывайте. - Неправильное смешение `.then/.catch` и `async/await`, приводящее к сложному управлению ошибками — держите стиль консистентным или явно возвращайте/пробрасывайте ошибки. - Не учтено поведение fetch: он не отвергает промис при HTTP-ошибках → нужно вручную проверять `res.ok`. - Отсутствие таймаута/отмены запросов → использовать AbortController. - Необработанные отказанные промисы (unhandled rejection) в Node могут привести к предупреждениям или завершению процесса — всегда обрабатывайте промисы. Короткая альтернатива с проверками: async function fetchData(){ const controller = new AbortController(); try{ const res = await fetch(url, { signal: controller.signal }); if (!res.ok) throw new Error(`HTTP ${res.status}`); return await res.json(); }catch(e){ console.error(e); throw e; }finally{ // очистка/отмена при необходимости } }
let res = fetch(url);
res становится Promise, а не объектом Response, поэтому вызов `res.json()` даёт ошибку (TypeError: res.json is not a function).
Как исправить (минимально):
async function fetchData(){
try{
const res = await fetch(url); // ← await здесь
const data = await res.json();
return data;
}catch(e){
console.log(e);
throw e; // по необходимости пробросить
}
}
Рекомендации по надёжности:
- Проверять HTTP-статус: `if (!res.ok) throw new Error(\`HTTP \${res.status}\`);` — fetch отклоняет промис только при сетевой ошибке, 4xx/5xx не считаются rejected.
- Обрабатывать возможную ошибку парсинга JSON в отдельном try/catch, если нужно различать ошибки.
- Использовать AbortController для отмены длительных запросов и предотвращения утечек.
Распространённые ошибки при работе с async/await (кратко и как исправлять):
- Забыл `await` перед промисом (как в примере) → получаешь промис вместо значения; добавить `await` или использовать `.then`.
- Ожидание внутри `try` без `await`: `try { someAsync(); } catch(e) {}` — catch не поймает ошибку. Нужно `await someAsync();`.
- Использование `Array.prototype.forEach` с `async`-колбэком — `forEach` не ждёт промисы. Используйте `for...of`, `Promise.all(...)` или `map`+`Promise.all`.
- Слишком последовательное выполнение там, где можно параллелить: делать `await` в цикле вызывает серию запросов последовательно; для параллели соберите промисы и `await Promise.all(promises)`.
- Поглощение ошибок (пустой catch или только логирование) — теряются ошибки; по необходимости пробрасывайте дальше или корректно обрабатывайте.
- Неправильное смешение `.then/.catch` и `async/await`, приводящее к сложному управлению ошибками — держите стиль консистентным или явно возвращайте/пробрасывайте ошибки.
- Не учтено поведение fetch: он не отвергает промис при HTTP-ошибках → нужно вручную проверять `res.ok`.
- Отсутствие таймаута/отмены запросов → использовать AbortController.
- Необработанные отказанные промисы (unhandled rejection) в Node могут привести к предупреждениям или завершению процесса — всегда обрабатывайте промисы.
Короткая альтернатива с проверками:
async function fetchData(){
const controller = new AbortController();
try{
const res = await fetch(url, { signal: controller.signal });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return await res.json();
}catch(e){
console.error(e);
throw e;
}finally{
// очистка/отмена при необходимости
}
}