Bloguons JavaScript

Parce que je me dis tout le temps : « Faut que j'écrive ça quelque part. »
Home

Aller au menu | Aller à la recherche

fetch(), la suite : annuler les requêtes

, 13:29 - Lien permanent

Dans mon billet sur fetch(), j'avais laissé entendre que je ne comprenais pas tout de la méthode.

En fait, il s'agissait de la façon d'annuler une requête faite avec fetch(). Alors j'ai étudié... et j'ai compris.

On va essayer de faire ça simple ici.

<button id='btn' type='button'>Requête</button>

<script>
let ab = new AbortController()
const btn = document.getElementById('btn');
btn.addEventListener('click', ev => {
    ab.abort();
    ab = new AbortController();
    fetch('/appel-ajax', {signal: ab.signal})
        .then(p => p.text())
        .then(data => console.log(data));
});
</script>

AbortController est un objet qui, comme son nom l'indique, permet de faire avorter des requêtes. Particularité : sa méthode abort() ne peut être appelée qu'une seule fois. C'est comme une allumette qu'on ne peut allumer qu'une fois.

Entre le moment où on créé l'instance AbortController via la variable ab, et le moment où l'on lance abort, on peut lancer une requête fetch en le liant à ab, en utilisant sa propriété signal. Ainsi, au moment où fetch() est en attente d'une réponse du serveur, si ab.abort() est exécuté, la requête fetch() est abandonnée, et le code à l'intérieur de ses .then() ne sera pas exécuté.

Dans cet exemple, la première fois que le bouton est cliqué, ab n'est lié à aucun fetch et abort() ne fait rien. Il brûle quand même ab, qui sera réaffecté à une nouvelle instance d'AbortController.

Au final, que même si le bouton Requête est cliqué 10 fois à intervalle d'une seconde entre chaque clic, et que la requête n'aboutit qu'après deux secondes, JavaScript n'attendra pas 10 réponses simultanément, mais seulement la dernière, qui arrivera deux secondes après le dernier clic. C'est ça qu'on veut!

Ah oui : On peut lier plusieurs fetch() à un objet AbortController. Lorsque sa méthode abort() est appelée, tous les requêtes liées seront abandonnées.