Nederlands

Leer hoe u JavaScript's AbortController gebruikt om asynchrone bewerkingen zoals fetch-verzoeken, timers en meer effectief te annuleren, voor schonere en betere code.

JavaScript AbortController: Asynchrone Bewerkingen Annuleren als een Pro

In moderne webontwikkeling zijn asynchrone bewerkingen alomtegenwoordig. Het ophalen van gegevens van API's, het instellen van timers en het afhandelen van gebruikersinteracties omvatten vaak code die onafhankelijk en mogelijk voor langere tijd wordt uitgevoerd. Er zijn echter scenario's waarin u deze bewerkingen moet annuleren voordat ze zijn voltooid. Dit is waar de AbortController interface in JavaScript te hulp schiet. Het biedt een schone en efficiënte manier om annuleringsverzoeken te signaleren naar DOM-bewerkingen en andere asynchrone taken.

Het Begrijpen van de Noodzaak tot Annulering

Voordat we ingaan op de technische details, laten we begrijpen waarom het annuleren van asynchrone bewerkingen belangrijk is. Denk aan deze veelvoorkomende scenario's:

Introductie van AbortController en AbortSignal

De AbortController interface is ontworpen om het probleem van het annuleren van asynchrone bewerkingen op te lossen. Het bestaat uit twee belangrijke componenten:

Basisgebruik: Fetch-verzoeken Annuleren

Laten we beginnen met een eenvoudig voorbeeld van het annuleren van een fetch verzoek:


const controller = new AbortController();
const signal = controller.signal;

fetch('https://api.example.com/data', { signal })
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    return response.json();
  })
  .then(data => {
    console.log('Data:', data);
  })
  .catch(error => {
    if (error.name === 'AbortError') {
      console.log('Fetch aborted');
    } else {
      console.error('Fetch error:', error);
    }
  });

// Om het fetch-verzoek te annuleren:
controller.abort();

Uitleg:

  1. We creëren een AbortController instantie.
  2. We verkrijgen het bijbehorende AbortSignal van de controller.
  3. We geven het signal door aan de fetch opties.
  4. Als we het verzoek moeten annuleren, roepen we controller.abort() aan.
  5. In het .catch() blok controleren we of de fout een AbortError is. Zo ja, dan weten we dat het verzoek is geannuleerd.

AbortError Afhandelen

Wanneer controller.abort() wordt aangeroepen, wordt het fetch verzoek afgewezen met een AbortError. Het is cruciaal om deze fout op de juiste manier in uw code af te handelen. Als u dit niet doet, kan dit leiden tot onafgehandelde promise-afwijzingen en onverwacht gedrag.

Hier is een robuuster voorbeeld met foutafhandeling:


const controller = new AbortController();
const signal = controller.signal;

async function fetchData() {
  try {
    const response = await fetch('https://api.example.com/data', { signal });
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    const data = await response.json();
    console.log('Data:', data);
    return data;
  } catch (error) {
    if (error.name === 'AbortError') {
      console.log('Fetch aborted');
      return null; // Of gooi de fout omhoog om verder afgehandeld te worden
    } else {
      console.error('Fetch error:', error);
      throw error; // Gooi de fout opnieuw om verder afgehandeld te worden
    }
  }
}

fetchData();

// Om het fetch-verzoek te annuleren:
controller.abort();

Best Practices voor het Afhandelen van AbortError:

Timers Annuleren met AbortSignal

De AbortSignal kan ook worden gebruikt om timers te annuleren die zijn gemaakt met setTimeout of setInterval. Dit vereist iets meer handmatig werk, omdat de ingebouwde timerfuncties AbortSignal niet direct ondersteunen. U moet een aangepaste functie maken die luistert naar het abort-signaal en de timer wist wanneer dit wordt geactiveerd.


function cancellableTimeout(callback, delay, signal) {
  let timeoutId;

  const timeoutPromise = new Promise((resolve, reject) => {
    timeoutId = setTimeout(() => {
      resolve(callback());
    }, delay);

    signal.addEventListener('abort', () => {
      clearTimeout(timeoutId);
      reject(new Error('Timeout Aborted'));
    });
  });

  return timeoutPromise;
}

const controller = new AbortController();
const signal = controller.signal;


cancellableTimeout(() => {
  console.log('Timeout executed');
}, 2000, signal)
.then(() => console.log("Timeout finished successfully"))
.catch(err => console.log(err));

// Om de timeout te annuleren:
controller.abort();

Uitleg:

  1. De cancellableTimeout functie accepteert een callback, een vertraging en een AbortSignal als argumenten.
  2. Het stelt een setTimeout in en slaat de timeout ID op.
  3. Het voegt een event listener toe aan de AbortSignal die luistert naar de abort event.
  4. Wanneer de abort event wordt geactiveerd, wist de event listener de timeout en wijst de promise af.

Event Listeners Annuleren

Net als bij timers, kunt u AbortSignal gebruiken om event listeners te annuleren. Dit is vooral handig wanneer u event listeners wilt verwijderen die zijn gekoppeld aan een component dat wordt ontkoppeld.


const controller = new AbortController();
const signal = controller.signal;

const button = document.getElementById('myButton');

button.addEventListener('click', () => {
  console.log('Button clicked!');
}, { signal });

// Om de event listener te annuleren:
controller.abort();

Uitleg:

  1. We geven het signal door als een optie aan de addEventListener methode.
  2. Wanneer controller.abort() wordt aangeroepen, wordt de event listener automatisch verwijderd.

AbortController in React Components

In React kunt u AbortController gebruiken om asynchrone bewerkingen te annuleren wanneer een component ontkoppelt. Dit is essentieel om geheugenlekken en fouten te voorkomen die worden veroorzaakt door het bijwerken van ontkoppelde componenten. Hier is een voorbeeld met behulp van de useEffect hook:


import React, { useState, useEffect } from 'react';

function MyComponent() {
  const [data, setData] = useState(null);

  useEffect(() => {
    const controller = new AbortController();
    const signal = controller.signal;

    async function fetchData() {
      try {
        const response = await fetch('https://api.example.com/data', { signal });
        if (!response.ok) {
          throw new Error(`HTTP error! Status: ${response.status}`);
        }
        const data = await response.json();
        setData(data);
      } catch (error) {
        if (error.name === 'AbortError') {
          console.log('Fetch aborted');
        } else {
          console.error('Fetch error:', error);
        }
      }
    }

    fetchData();

    return () => {
      controller.abort(); // Annuleer het fetch-verzoek wanneer de component ontkoppelt
    };
  }, []); // Lege dependency array zorgt ervoor dat dit effect slechts één keer wordt uitgevoerd bij het monteren

  return (
    
{data ? (

Data: {JSON.stringify(data)}

) : (

Loading...

)}
); } export default MyComponent;

Uitleg:

  1. We creëren een AbortController binnen de useEffect hook.
  2. We geven het signal door aan het fetch verzoek.
  3. We retourneren een cleanup functie van de useEffect hook. Deze functie wordt aangeroepen wanneer de component ontkoppelt.
  4. Binnen de cleanup functie roepen we controller.abort() aan om het fetch-verzoek te annuleren.

Geavanceerde Gebruiksscenario's

AbortSignals Chaining

Soms wilt u mogelijk meerdere AbortSignals aan elkaar koppelen. U hebt bijvoorbeeld een bovenliggende component die bewerkingen in de onderliggende componenten moet annuleren. U kunt dit bereiken door een nieuwe AbortController te maken en het signaal ervan door te geven aan zowel de bovenliggende als de onderliggende component.

AbortController Gebruiken met Third-Party Libraries

Als u een third-party library gebruikt die AbortSignal niet direct ondersteunt, moet u mogelijk uw code aanpassen om met het annuleringsmechanisme van de library te werken. Dit kan inhouden dat u de asynchrone functies van de library verpakt in uw eigen functies die de AbortSignal afhandelen.

Voordelen van het Gebruiken van AbortController

Browsercompatibiliteit

AbortController wordt breed ondersteund in moderne browsers, waaronder Chrome, Firefox, Safari en Edge. U kunt de compatibiliteitstabel op de MDN Web Docs raadplegen voor de meest recente informatie.

Polyfills

Voor oudere browsers die AbortController niet native ondersteunen, kunt u een polyfill gebruiken. Een polyfill is een stuk code dat de functionaliteit van een nieuwere functie in oudere browsers biedt. Er zijn verschillende AbortController polyfills online beschikbaar.

Conclusie

De AbortController interface is een krachtig hulpmiddel voor het beheren van asynchrone bewerkingen in JavaScript. Door AbortController te gebruiken, kunt u schonere, beter presterende en robuustere code schrijven die annulering elegant afhandelt. Of u nu gegevens ophaalt van API's, timers instelt of event listeners beheert, AbortController kan u helpen de algehele kwaliteit van uw webapplicaties te verbeteren.

Verder Lezen