W3docs

Fetch : annulation

Apprenez à annuler des requêtes fetch en JavaScript avec AbortController et AbortSignal : annulations déclenchées par l'utilisateur, délais d'attente, annulation de plusieurs requêtes et gestion de AbortError.

Une fois qu'une requête fetch() est en cours, elle continue à s'exécuter jusqu'à ce que le serveur réponde — même si l'utilisateur a navigué ailleurs, saisi un nouveau terme de recherche, ou que la réponse n'est plus nécessaire. Ces requêtes inutiles monopolisent les connexions, consomment la batterie et la bande passante, et peuvent délivrer des résultats obsolètes qui écrasent des résultats récents. L'interface AbortController vous offre un moyen propre et standardisé d'annuler une requête à la demande.

Ce chapitre montre comment câbler AbortController, réagir aux actions de l'utilisateur, mettre en place des délais d'attente, annuler plusieurs requêtes à la fois et gérer correctement l'AbortError résultant. Pour en savoir plus sur fetch lui-même, consultez la page précédente, Fetch API.

Fonctionnement de AbortController

AbortController est un petit objet avec une seule mission : il possède un AbortSignal et peut faire passer ce signal à l'état annulé. Le signal est la partie que vous transmettez à fetch() (ainsi qu'à de nombreuses autres API navigateur, comme addEventListener). Lorsque vous appelez controller.abort(), toutes les opérations qui ont reçu ce signal sont annulées.

Le schéma est toujours le même en trois étapes :

  1. Créer un contrôleur : const controller = new AbortController().
  2. Passer controller.signal à fetch() dans l'objet d'options.
  3. Appeler controller.abort() dès que vous souhaitez annuler.

Lorsqu'un fetch est annulé, sa promesse est rejetée avec une DOMException dont le name est "AbortError". C'est pourquoi chaque exemple ci-dessous vérifie error.name === 'AbortError' — afin d'ignorer l'annulation délibérée tout en remontant les vraies erreurs réseau.

Utilisation basique de AbortController

Voici le plus petit exemple complet. Il effectue l'annulation immédiatement pour que vous puissiez observer le chemin de rejet :

javascript— editable

Nous créons un AbortController, passons son signal à fetch(), et appelons immédiatement controller.abort(). Étant donné que la requête ne se termine jamais normalement, le .catch() s'exécute et signale l'annulation.

Inspecter le signal : aborted et l'événement abort

Le signal expose son état afin que d'autres parties du code puissent réagir à une annulation. Deux membres sont les plus importants :

  • signal.aborted — un boolean qui devient true une fois annulé.
  • l'événement "abort" — déclenché sur le signal dès que abort() est appelé.
javascript— editable

C'est pratique lorsque vous avez des traitements non-fetch (un minuteur, une animation, un lecteur de flux) qui doivent s'arrêter dès que la requête est annulée.

Un contrôleur, une utilisation. Un contrôleur ne peut pas être réinitialisé. Une fois que vous avez appelé abort(), ce signal reste annulé définitivement, et tout nouveau fetch() démarré avec lui sera rejeté instantanément. Pour une nouvelle requête, créez un nouvel AbortController.

Exemple pratique : annulation déclenchée par une action utilisateur

La raison la plus courante d'annuler est qu'un utilisateur change d'avis — en cliquant sur « Annuler », en fermant une boîte de dialogue, ou en tapant une nouvelle requête avant que la précédente soit terminée. Ici, un bouton annule une requête en cours :

<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>

Cliquer sur le bouton ayant l'ID abortButton annule la requête fetch en cours. Le point de terminaison https://httpbin.org/delay/5 prend délibérément 5 secondes, donc si vous cliquez dans ce délai, la requête est rejetée avec AbortError.

Annuler plusieurs requêtes à la fois

Un seul signal peut être passé à de nombreuses requêtes. Un seul appel à controller.abort() les annule toutes — pratique lorsqu'une page quitte une vue qui avait lancé plusieurs chargements en parallèle :

javascript— editable

Puisque les trois requêtes partagent un seul signal, controller.abort() les annule en un seul appel et Promise.all est rejeté avec AbortError. Pour en savoir plus sur l'exécution de requêtes en parallèle, consultez Promise API.

Annuler après un délai d'attente

Un usage très courant de AbortController est de donner une limite de temps à une requête : si le serveur est trop lent, annuler et afficher une erreur plutôt qu'attendre indéfiniment.

La méthode manuelle avec setTimeout

Vous pouvez associer le contrôleur à un minuteur et le combiner avec toute autre logique asynchrone. Ici, une opération distincte déclenche l'annulation après une seconde, alors que le point de terminaison prendrait cinq secondes :

javascript— editable

Le fetch est annulé par le minuteur après une seconde, bien avant que le point de terminaison à cinq secondes puisse répondre. Pour en savoir plus sur les minuteurs, consultez async/await.

Le raccourci : AbortSignal.timeout()

Les navigateurs modernes (et Node 17.3+) embarquent un assistant intégré qui crée un signal s'annulant automatiquement après un nombre donné de millisecondes — sans contrôleur ni setTimeout :

javascript— editable

Notez qu'une annulation par délai d'attente génère un rejet avec TimeoutError et non AbortError, vous permettant ainsi de distinguer « trop lent » de « l'utilisateur a annulé ». Si vous avez besoin à la fois d'un délai d'attente et d'un bouton d'annulation manuel, combinez les signaux avec AbortSignal.any([userSignal, AbortSignal.timeout(2000)]).

Gérer AbortError correctement

Chaque fois que vous annulez un fetch, la promesse est rejetée. Oublier de le gérer produit un bruyant « uncaught promise rejection » dans la console, même si l'annulation était intentionnelle. Deux règles permettent de garder les choses propres :

  • Toujours avoir un .catch() (ou try/catch avec await) sur un fetch annulable.
  • À l'intérieur, vérifier error.name et traiter 'AbortError' / 'TimeoutError' comme attendus — seules les autres erreurs doivent être journalisées ou remontées. Consultez Gestion des erreurs avec les promesses pour le schéma général.

Conclusion

AbortController est la manière standard d'annuler des requêtes fetch() en JavaScript. Créez un contrôleur, passez son signal à une ou plusieurs requêtes, et appelez abort() dès que le travail n'est plus nécessaire. Vous avez vu l'annulation déclenchée par l'utilisateur, les délais d'attente manuels et intégrés, l'annulation de plusieurs requêtes à la fois, et comment gérer l'AbortError résultant. Utiliser ces schémas maintient vos applications réactives et évite de gaspiller du temps sur des résultats que personne n'attend plus.

Pratique

Pratique
Quel est le rôle du passage de la propriété signal d'un AbortController à une requête fetch ?
Quel est le rôle du passage de la propriété signal d'un AbortController à une requête fetch ?
Was this page helpful?