Slovenčina

Naučte sa používať JavaScript AbortController na efektívne zrušenie asynchrónnych operácií, ako sú fetch požiadavky, časovače a ďalšie, čím zabezpečíte čistejší a výkonnejší kód.

JavaScript AbortController: Ovládanie zrušenia asynchrónnych operácií

V modernom webovom vývoji sú asynchrónne operácie všadeprítomné. Získavanie dát z API, nastavovanie časovačov a spracovanie interakcií používateľa často zahŕňa kód, ktorý beží nezávisle a potenciálne aj dlhšiu dobu. Existujú však scenáre, kde potrebujete tieto operácie zrušiť predtým, ako sa dokončia. Práve tu prichádza na pomoc rozhranie AbortController v JavaScripte. Poskytuje čistý a efektívny spôsob signalizácie požiadaviek na zrušenie operácií DOM a iných asynchrónnych úloh.

Pochopenie potreby zrušenia

Predtým, ako sa ponoríme do technických detailov, poďme pochopiť, prečo je zrušenie asynchrónnych operácií dôležité. Zvážte tieto bežné scenáre:

Predstavujeme AbortController a AbortSignal

Rozhranie AbortController je navrhnuté tak, aby riešilo problém zrušenia asynchrónnych operácií. Skladá sa z dvoch kľúčových komponentov:

Základné použitie: Zrušenie Fetch požiadaviek

Začnime s jednoduchým príkladom zrušenia požiadavky fetch:


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

// To cancel the fetch request:
controller.abort();

Vysvetlenie:

  1. Vytvoríme inštanciu AbortController.
  2. Získame pridružený AbortSignal z controller.
  3. Odovzdáme signal do fetch options.
  4. Ak potrebujeme zrušiť požiadavku, zavoláme controller.abort().
  5. V bloku .catch() skontrolujeme, či je chyba AbortError. Ak áno, vieme, že požiadavka bola zrušená.

Spracovanie AbortError

Keď sa zavolá controller.abort(), požiadavka fetch bude odmietnutá s chybou AbortError. Je dôležité správne spracovať túto chybu vo vašom kóde. Ak to neurobíte, môže to viesť k nespracovaným odmietnutiam promise a neočakávanému správaniu.

Tu je robustnejší príklad so spracovaním chýb:


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; // Or throw the error to be handled further up
    } else {
      console.error('Fetch error:', error);
      throw error; // Re-throw the error to be handled further up
    }
  }
}

fetchData();

// To cancel the fetch request:
controller.abort();

Osvedčené postupy pre spracovanie AbortError:

Zrušenie časovačov pomocou AbortSignal

AbortSignal sa dá použiť aj na zrušenie časovačov vytvorených pomocou setTimeout alebo setInterval. To si vyžaduje trochu viac manuálnej práce, pretože vstavané funkcie časovača nepodporujú priamo AbortSignal. Musíte vytvoriť vlastnú funkciu, ktorá počúva signál prerušenia a vymaže časovač, keď sa spustí.


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

// To cancel the timeout:
controller.abort();

Vysvetlenie:

  1. Funkcia cancellableTimeout preberá callback, oneskorenie a AbortSignal ako argumenty.
  2. Nastaví setTimeout a uloží ID časového limitu.
  3. Pridá poslucháča udalostí do AbortSignal, ktorý počúva udalosť abort.
  4. Keď sa spustí udalosť abort, poslucháč udalostí vymaže časový limit a odmietne promise.

Zrušenie poslucháčov udalostí

Podobne ako pri časovačoch, môžete použiť AbortSignal na zrušenie poslucháčov udalostí. To je užitočné najmä vtedy, keď chcete odstrániť poslucháčov udalostí spojených s komponentom, ktorý sa odmontováva.


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

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

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

// To cancel the event listener:
controller.abort();

Vysvetlenie:

  1. Odovzdáme signal ako možnosť metóde addEventListener.
  2. Keď sa zavolá controller.abort(), poslucháč udalostí sa automaticky odstráni.

AbortController v React komponentoch

V React môžete použiť AbortController na zrušenie asynchrónnych operácií, keď sa komponent odmontuje. To je nevyhnutné na zabránenie únikom pamäte a chybám spôsobeným aktualizáciou odmontovaných komponentov. Tu je príklad pomocou hooku useEffect:


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(); // Cancel the fetch request when the component unmounts
    };
  }, []); // Empty dependency array ensures this effect runs only once on mount

  return (
    
{data ? (

Data: {JSON.stringify(data)}

) : (

Loading...

)}
); } export default MyComponent;

Vysvetlenie:

  1. Vytvoríme AbortController v rámci hooku useEffect.
  2. Odovzdáme signal do požiadavky fetch.
  3. Vrátime funkciu vyčistenia z hooku useEffect. Táto funkcia sa zavolá, keď sa komponent odmontuje.
  4. Vo funkcii vyčistenia zavoláme controller.abort() na zrušenie požiadavky fetch.

Pokročilé prípady použitia

Reťazenie AbortSignals

Niekedy možno budete chcieť zreťaziť viacero AbortSignal dohromady. Napríklad môžete mať nadradený komponent, ktorý potrebuje zrušiť operácie vo svojich podradených komponentoch. Môžete to dosiahnuť vytvorením nového AbortController a odovzdaním jeho signálu nadradenému aj podradenému komponentu.

Používanie AbortController s knižnicami tretích strán

Ak používate knižnicu tretej strany, ktorá priamo nepodporuje AbortSignal, možno budete musieť prispôsobiť svoj kód tak, aby fungoval s mechanizmom zrušenia knižnice. To môže zahŕňať zabalenie asynchrónnych funkcií knižnice do vlastných funkcií, ktoré spracovávajú AbortSignal.

Výhody používania AbortController

Kompatibilita prehliadača

AbortController je široko podporovaný v moderných prehliadačoch, vrátane Chrome, Firefox, Safari a Edge. Najnovšie informácie nájdete v tabuľke kompatibility na MDN Web Docs.

Polyfilly

Pre staršie prehliadače, ktoré natívne nepodporujú AbortController, môžete použiť polyfill. Polyfill je časť kódu, ktorá poskytuje funkčnosť novšej funkcie v starších prehliadačoch. Existuje niekoľko AbortController polyfillov dostupných online.

Záver

Rozhranie AbortController je výkonný nástroj na správu asynchrónnych operácií v JavaScripte. Používaním AbortController môžete písať čistejší, výkonnejší a robustnejší kód, ktorý elegantne spracováva zrušenie. Či už získavate dáta z API, nastavujete časovače alebo spravujete poslucháčov udalostí, AbortController vám môže pomôcť zlepšiť celkovú kvalitu vašich webových aplikácií.

Ďalšie čítanie