Ce face AbortController / AbortSignal.timeout
Un AbortController are un signal, pe care îl dai operației (lui fetch, unui addEventListener sau propriilor funcții). Când apelezi abort(motiv), operația se oprește și promisiunea ei este respinsă cu o eroare AbortError (sau cu motivul dat).
Metode statice utile: AbortSignal.timeout(ms) creează un semnal care se declanșează singur după un timp (eroare TimeoutError), AbortSignal.any([s1, s2]) se declanșează la primul dintre semnale, iar AbortSignal.abort() creează un semnal deja declanșat. În funcțiile tale, signal.throwIfAborted() aruncă eroarea dacă semnalul a fost declanșat.
Parametri
| Parametru | Descriere |
|---|---|
motiv |
Opțional, pentru abort: motivul opririi (implicit o eroare AbortError). |
Ce returnează
Un controller cu proprietatea signal.
Exemple
Exemplul 1: Oprire la comandă într-o funcție proprie
function numara(signal) {
return new Promise((resolve, reject) => {
let n = 0;
const id = setInterval(() => console.log(++n), 50);
signal.addEventListener("abort", () => {
clearInterval(id);
reject(signal.reason);
});
});
}
const controller = new AbortController();
setTimeout(() => controller.abort(), 175);
try {
await numara(controller.signal);
} catch (e) {
console.log(e.name);
}
Rezultat
1
2
3
AbortError
Exemplul 2: Limită de timp și semnale combinate
const pauza = (ms, signal) => new Promise((resolve, reject) => {
const id = setTimeout(resolve, ms);
signal.addEventListener("abort", () => { clearTimeout(id); reject(signal.reason); });
});
try {
await pauza(1000, AbortSignal.timeout(100));
} catch (e) {
console.log(e.name);
}
const utilizator = new AbortController();
const semnal = AbortSignal.any([utilizator.signal, AbortSignal.timeout(5000)]);
utilizator.abort(new Error("Anulat de utilizator"));
console.log(semnal.aborted, semnal.reason.message);
try {
AbortSignal.abort().throwIfAborted();
} catch (e) {
console.log(e.name);
}
Rezultat
TimeoutError
true Anulat de utilizator
AbortError
Exemplul 3: fetch cu limită de 5 secunde
try {
const raspuns = await fetch("https://api.lenta.exemplu.ro/raport", { signal: AbortSignal.timeout(5000) });
console.log(await raspuns.json());
} catch (e) {
if (e.name === "TimeoutError") console.log("Serverul nu a răspuns în 5 secunde");
else throw e;
}
Rezultat posibil (depinde de răspunsul serverului)
Serverul nu a răspuns în 5 secunde
Greșeli frecvente
- Refolosești un controller după
abort(). Semnalul rămâne declanșat pentru totdeauna; creează un controller nou pentru fiecare cerere. - Tratezi oprirea ca pe o eroare reală și afișezi un mesaj de eroare utilizatorului. Verifică
e.name === "AbortError"și ignoră cazul.
Comenzi înrudite
fetch: Trimite o cerere HTTP la un server și primește răspunsul, fără reîncărcarea paginii.Promise.race: Returnează rezultatul (sau eroarea) primei promisiuni care se termină.addEventListener: Rulează o funcție când se întâmplă ceva pe pagină: un clic, o tastă, trimiterea unui formular.