Definiowanie timeoutów z Fetch API
Obecnie definiowanie timeoutów jest bardzo proste. Wystarczy wywołać metodę statyczną AbortSignal.timeout(), która zwraca signal, który natomiast przekazujemy do fetch.
const response = await fetch(url, {
signal: AbortSignal.timeout(2000) // 2 sekundy
});
Obsługa wyjątków
Gdy odpowiedź z serwera będzie dłuższa niż zdefiniowany timeout, fetch rzuci wyjątkiem TimeoutError.
try {
await fetch(url, {
signal: AbortSignal.timeout(2000) // 2 sekundy
});
} catch (err) {
if (err.name === 'TimeoutError') {
// tutaj możesz obsłużyć wyjątek
}
}
Wsparcie przeglądarek
AbortSignal: timeout() w 2025 ma dość solidne wsparcie. Funkcjonalność na dzień pisania artykułu obsługiwana jest przez ~93% wersji przeglądarek.
Alternatywne podejście
AbortController: abort() pozwala przerwać request z dowolnego powodu. Jako że artykuł skupia się na timeoutach to pokażę Ci, jak również go obsłużyć za pomocą tej metody.
const abortController = new AbortController()
const timeoutId = setTimeout(
() => abortController.abort(),
2000, // 2 sekundy
)
try {
await fetch(url, { signal: abortController.signal })
clearTimeout(timeoutId)
} catch (err) {
if (err.name === 'AbortError') {
// tutaj możesz obsłużyć wyjątek
}
}
Jak wspomniałem, możesz użyć .abort() dla dowolnego powodu. Na przykład, aby anulować zapytanie HTTP po kliknięciu przycisku:
const button = document.querySelector('button')
const abortController = new AbortController()
button.onclick = () => abortController.abort() // `addEventListener` jest lepszy, ale `onclick` jest krótszy do celów prezentacji.
try {
fetch(url, { signal: abortController.signal }) // `await` jest pominięty celowo
button.click()
} catch (err) {
if (err.name === 'AbortError') {
// tutaj możesz obsłużyć wyjątek
}
}
Bibliografia
- Fetch API
AbortControllerAbortController: abort()AbortController: signalAbortSignal: timeout()TimeoutError