Fetch / XHR: Таймаут и отмена через AbortController

Зависшие запросы портят 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, чтобы не зависал экран.
  • Длительные загрузки (превью, экспорты).
  • Сложные интеграции: лучше упасть быстро и показать понятный статус.
1.2 г. Просмотров: 431
Материал помог? Оценка помогает находить устаревшие и спорные решения.

Комментарии

0

Нашли ошибку или хотите дополнить материал?

Комментариев пока нет.Можно первым дополнить материал или сообщить об ошибке.
Telegram