Definiowanie timeoutów z Fetch API

  • javascript

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

Zobacz także