Зависшие запросы портят UX. Нужно уметь автоматически отменять их, чтобы интерфейс не замерзал.
AbortController создаёт сигнал отмены, который передаётся в fetch. При срабатывании таймера мы вызываем controller.abort(), и запрос завершается с ошибкой AbortError.
1. Код с таймаутом
function withTimeout(ms)
{
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort('timeout'), ms);
return {controller, timeoutId};
}
async function fetchWithTimeout(url, opts = {}, timeoutMs = 8000)
{
if (typeof url !== 'string' || !url) throw new Error('Некорректный URL');
const {controller, timeoutId} = withTimeout(timeoutMs);
try
{
const response = await fetch(url, {...opts, signal: controller.signal});
return response;
}
finally
{
clearTimeout(timeoutId);
}
}
2. Пример использования
(async () => {
try {
const res = await fetchWithTimeout('https://api.example.com/slow', {}, 5000);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
console.log('Данные:', data);
} catch (err) {
if (err.name === 'AbortError') {
console.error('Запрос отменён по таймауту');
} else {
console.error('Ошибка:', err.message);
}
}
})();
Где применять
- SPA/PWA, чтобы не зависал экран.
- Длительные загрузки (превью, экспорты).
- Сложные интеграции: лучше упасть быстро и показать понятный статус.
Комментарии
0Нашли ошибку или хотите дополнить материал?