Fetch: abort
Impara ad annullare le richieste fetch in JavaScript con AbortController e AbortSignal: abort attivati dall'utente, timeout, annullamento multiplo e gestione corretta di AbortError.
Una volta che una richiesta fetch() è in corso, continua a essere eseguita finché il server non risponde — anche se l'utente ha navigato altrove, digitato un nuovo termine di ricerca o il risultato non è più necessario. Queste richieste sprecate occupano connessioni, consumano batteria e banda, e possono consegnare risultati obsoleti che sovrascrivono quelli più recenti. L'interfaccia AbortController offre un modo pulito e standard per annullare una richiesta su richiesta.
Questo capitolo mostra come collegare AbortController, reagire alle azioni dell'utente, costruire timeout, annullare più richieste contemporaneamente e gestire correttamente l'AbortError risultante. Per saperne di più su fetch stesso, consulta la pagina precedente, Fetch API.
Come funziona AbortController
AbortController è un piccolo oggetto con un solo compito: possiede un AbortSignal e può portare quel segnale allo stato abortito. Il segnale è la parte che passi a fetch() (e a molte altre API del browser, come addEventListener). Quando chiami controller.abort(), ogni operazione che ha ricevuto quel segnale viene annullata.
Il pattern prevede sempre tre passaggi:
- Crea un controller:
const controller = new AbortController(). - Passa
controller.signalafetch()nell'oggetto opzioni. - Chiama
controller.abort()ogni volta che vuoi annullare.
Quando un fetch viene annullato, la sua promise rigetta con un DOMException il cui name è "AbortError". Ecco perché ogni esempio qui sotto controlla error.name === 'AbortError' — in modo da poter ignorare la cancellazione intenzionale, pur visualizzando i veri errori di rete.
Utilizzo di base di AbortController
Ecco il più piccolo esempio completo. Si annulla immediatamente per mostrare il percorso di rifiuto:
Creiamo un AbortController, passiamo il suo signal a fetch() e chiamiamo immediatamente controller.abort(). Poiché la richiesta non viene mai completata normalmente, viene eseguito il .catch() che segnala l'interruzione.
Ispezione del segnale: aborted e l'evento abort
Il segnale espone il suo stato in modo che altri elementi del codice possano reagire a una cancellazione. Due membri sono i più importanti:
signal.aborted— un boolean che diventatrueuna volta annullato.- l'evento
"abort"— attivato sul segnale nel momento in cui viene chiamatoabort().
Questo è utile quando hai del lavoro non-fetch (un timer, un'animazione, un lettore di stream) che dovrebbe fermarsi nel momento in cui la richiesta viene annullata.
Un controller, un utilizzo. Un controller non può essere resettato. Una volta chiamato
abort(), quel segnale rimane annullato per sempre, e qualsiasi nuovofetch()avviato con esso viene rigettato istantaneamente. Per una nuova richiesta, crea un nuovoAbortController.
Esempio pratico: annullamento su un'azione dell'utente
Il motivo più comune per annullare è che l'utente cambia idea — facendo clic su "Annulla", chiudendo un dialogo o digitando una nuova query prima che la precedente fosse completata. Qui un pulsante annulla una richiesta in corso:
<body>
<button id="abortButton">Abort Fetch Request</button>
<script>
const controller = new AbortController();
const signal = controller.signal;
document.getElementById('abortButton').addEventListener('click', () => {
controller.abort();
});
fetch('https://httpbin.org/delay/5', { signal })
.then(response => response.json())
.then(data => alert(
'Data is successfully fetched! Refresh the page and try aborting.'
))
.catch(error => {
if (error.name === 'AbortError') {
alert('Fetch request was aborted by the user');
} else {
alert('Fetch error: ' + error.message);
}
});
</script>
</body>Fare clic sul pulsante con l'ID abortButton annulla la richiesta fetch in corso. L'endpoint https://httpbin.org/delay/5 impiega deliberatamente 5 secondi, quindi se si fa clic entro quell'intervallo, la richiesta viene rigettata con AbortError.
Annullamento di più richieste contemporaneamente
Un singolo segnale può essere passato a molte richieste. Una chiamata a controller.abort() le annulla tutte — utile quando una pagina abbandona una vista che aveva avviato diversi carichi paralleli:
Poiché tutte e tre le richieste condividono un unico segnale, controller.abort() le annulla con una singola chiamata e Promise.all rigetta con AbortError. Per saperne di più sull'esecuzione di richieste in parallelo, consulta Promise API.
Annullamento dopo un timeout
Un uso molto comune di AbortController è quello di assegnare una scadenza a una richiesta: se il server è troppo lento, annulla e mostra un errore invece di aspettare all'infinito.
Il metodo manuale con setTimeout
Puoi abbinare il controller a un timer e combinarlo con qualsiasi altra logica asincrona. Qui un'operazione separata attiva l'annullamento dopo un secondo, mentre l'endpoint impiegherebbe cinque:
Il fetch viene annullato dal timer dopo un secondo, ben prima che l'endpoint da cinque secondi possa rispondere. Leggi di più sui timer in async/await.
La scorciatoia: AbortSignal.timeout()
I browser moderni (e Node 17.3+) includono un helper integrato che crea un segnale che si annulla da solo dopo un dato numero di millisecondi — senza bisogno di controller o setTimeout:
Nota che un abort per timeout rigetta con un TimeoutError, non con un AbortError, così puoi distinguere "ha impiegato troppo tempo" da "l'utente ha annullato". Se hai bisogno sia di un timeout sia di un pulsante di annullamento manuale, combina i segnali con AbortSignal.any([userSignal, AbortSignal.timeout(2000)]).
Gestione corretta di AbortError
Ogni volta che si annulla un fetch, la promise rigetta. Dimenticarsi di gestirlo produce un fastidioso "uncaught promise rejection" nella console, anche se la cancellazione era intenzionale. Due regole mantengono le cose pulite:
- Avere sempre un
.catch()(otry/catchconawait) su un fetch annullabile. - Al suo interno, controlla
error.namee tratta'AbortError'/'TimeoutError'come previsto — logga o mostra solo gli altri errori. Consulta Gestione degli errori con le promise per il pattern più generale.
Conclusione
AbortController è il modo standard per annullare le richieste fetch() in JavaScript. Crea un controller, passa il suo signal a una o più richieste e chiama abort() ogni volta che il lavoro non è più necessario. Hai visto la cancellazione attivata dall'utente, i timeout manuali e integrati, l'annullamento di più richieste contemporaneamente e come gestire l'AbortError risultante. Adottare questi pattern mantiene le tue app reattive e impedisce loro di sprecare tempo su risultati che nessuno sta più aspettando.