Norsk

Lær hvordan du bruker JavaScripts AbortController for effektivt å avbryte asynkrone operasjoner som fetch-forespørsler, tidtakere og mer, for renere og mer effektiv kode.

JavaScript AbortController: Mestre Avbrudd av Asynkrone Operasjoner

I moderne webutvikling er asynkrone operasjoner allestedsnærværende. Henting av data fra APIer, innstilling av tidtakere og håndtering av brukerinteraksjoner involverer ofte kode som kjører uavhengig og potensielt over lengre tid. Det finnes imidlertid scenarier der du trenger å avbryte disse operasjonene før de er fullført. Det er her AbortController-grensesnittet i JavaScript kommer til unnsetning. Det gir en ren og effektiv måte å signalisere kanselleringsforespørsler til DOM-operasjoner og andre asynkrone oppgaver.

Forstå Behovet for Kansellering

Før vi dykker ned i de tekniske detaljene, la oss forstå hvorfor det er viktig å kansellere asynkrone operasjoner. Vurder disse vanlige scenariene:

Introduserer AbortController og AbortSignal

AbortController-grensesnittet er utviklet for å løse problemet med å kansellere asynkrone operasjoner. Det består av to nøkkelkomponenter:

Grunnleggende Bruk: Kansellere Fetch-forespørsler

La oss starte med et enkelt eksempel på å kansellere en fetch-forespørsel:


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);
    }
  });

// For å kansellere fetch-forespørselen:
controller.abort();

Forklaring:

  1. Vi oppretter en AbortController-instans.
  2. Vi henter den tilknyttede AbortSignal fra controller.
  3. Vi sender signal til fetch-alternativene.
  4. Hvis vi trenger å kansellere forespørselen, kaller vi controller.abort().
  5. I .catch()-blokken sjekker vi om feilen er en AbortError. Hvis det er det, vet vi at forespørselen ble kansellert.

Håndtere AbortError

Når controller.abort() kalles, vil fetch-forespørselen bli avvist med en AbortError. Det er viktig å håndtere denne feilen på riktig måte i koden din. Unnlatelse av å gjøre det kan føre til uhåndterte promise-avvisninger og uventet oppførsel.

Her er et mer robust eksempel med feilhåndtering:


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; // Eller kast feilen for å bli håndtert lenger opp
    } else {
      console.error('Fetch error:', error);
      throw error; // Kast feilen på nytt for å bli håndtert lenger opp
    }
  }
}

fetchData();

// For å kansellere fetch-forespørselen:
controller.abort();

Beste Praksis for Håndtering av AbortError:

Kansellere Tidtakere med AbortSignal

AbortSignal kan også brukes til å kansellere tidtakere opprettet med setTimeout eller setInterval. Dette krever litt mer manuelt arbeid, siden de innebygde timerfunksjonene ikke støtter AbortSignal direkte. Du må opprette en tilpasset funksjon som lytter etter avbrytelsessignalet og fjerner tidtakeren når den utløses.


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

// For å kansellere tidsavbruddet:
controller.abort();

Forklaring:

  1. cancellableTimeout-funksjonen tar en callback, en forsinkelse og en AbortSignal som argumenter.
  2. Den setter opp en setTimeout og lagrer tidsavbrudds-IDen.
  3. Den legger til en hendelseslytter til AbortSignal som lytter etter abort-hendelsen.
  4. Når abort-hendelsen utløses, fjerner hendelseslytteren tidsavbruddet og avviser promise.

Kansellere Hendelseslyttere

På samme måte som tidtakere, kan du bruke AbortSignal til å kansellere hendelseslyttere. Dette er spesielt nyttig når du vil fjerne hendelseslyttere knyttet til en komponent som blir avmontert.


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

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

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

// For å kansellere hendelseslytteren:
controller.abort();

Forklaring:

  1. Vi sender signal som et alternativ til addEventListener-metoden.
  2. Når controller.abort() kalles, vil hendelseslytteren automatisk bli fjernet.

AbortController i React-komponenter

I React kan du bruke AbortController til å kansellere asynkrone operasjoner når en komponent avmonteres. Dette er viktig for å forhindre minnelekkasjer og feil forårsaket av oppdatering av avmonterte komponenter. Her er et eksempel ved hjelp av useEffect-hooken:


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(); // Kanseller fetch-forespørselen når komponenten avmonteres
    };
  }, []); // Tom avhengighetsarray sikrer at denne effekten bare kjøres én gang ved montering

  return (
    
{data ? (

Data: {JSON.stringify(data)}

) : (

Loading...

)}
); } export default MyComponent;

Forklaring:

  1. Vi oppretter en AbortController i useEffect-hooken.
  2. Vi sender signal til fetch-forespørselen.
  3. Vi returnerer en oppryddingsfunksjon fra useEffect-hooken. Denne funksjonen vil bli kalt når komponenten avmonteres.
  4. Inne i oppryddingsfunksjonen kaller vi controller.abort() for å kansellere fetch-forespørselen.

Avanserte Brukstilfeller

Kjede Sammen AbortSignals

Noen ganger kan det være lurt å kjede sammen flere AbortSignals. For eksempel kan du ha en overordnet komponent som trenger å kansellere operasjoner i sine underkomponenter. Du kan oppnå dette ved å opprette en ny AbortController og sende signalet til både den overordnede og underordnede komponenten.

Bruke AbortController med Tredjepartsbiblioteker

Hvis du bruker et tredjepartsbibliotek som ikke støtter AbortSignal direkte, må du kanskje tilpasse koden din til å fungere med bibliotekets kanselleringsmekanisme. Dette kan innebære å pakke bibliotekets asynkrone funksjoner inn i dine egne funksjoner som håndterer AbortSignal.

Fordeler med Å Bruke AbortController

Nettleserkompatibilitet

AbortController er bredt støttet i moderne nettlesere, inkludert Chrome, Firefox, Safari og Edge. Du kan sjekke kompatibilitetstabellen på MDN Web Docs for den nyeste informasjonen.

Polyfills

For eldre nettlesere som ikke støtter AbortController nativt, kan du bruke en polyfill. En polyfill er en kodebit som gir funksjonaliteten til en nyere funksjon i eldre nettlesere. Det finnes flere AbortController-polyfills tilgjengelig på nettet.

Konklusjon

AbortController-grensesnittet er et kraftig verktøy for å administrere asynkrone operasjoner i JavaScript. Ved å bruke AbortController kan du skrive renere, mer effektiv og mer robust kode som håndterer kansellering på en elegant måte. Enten du henter data fra APIer, setter tidtakere eller administrerer hendelseslyttere, kan AbortController hjelpe deg med å forbedre den generelle kvaliteten på webapplikasjonene dine.

Videre Lesning