Naučite se uporabljati JavaScriptov AbortController za učinkovito preklic asinhronih operacij, kot so zahteve za pridobivanje, časovniki in drugo, kar zagotavlja čistejšo in bolj zmogljivo kodo.
JavaScript AbortController: Obvladovanje prekinitve asinhronih operacij
V sodobnem spletnem razvoju so asinkrone operacije vseprisotne. Pridobivanje podatkov iz API-jev, nastavitev časovnikov in obravnavanje uporabniških interakcij pogosto vključuje kodo, ki se izvaja neodvisno in potencialno dalj časa. Vendar pa obstajajo scenariji, kjer morate te operacije preklicati, preden se zaključijo. Tu na pomoč priskoči vmesnik AbortController
v JavaScriptu. Omogoča čist in učinkovit način za signaliziranje zahtevkov za preklic DOM operacij in drugih asinhronih opravil.
Razumevanje potrebe po preklicu
Preden se poglobimo v tehnične podrobnosti, razumemo, zakaj je preklic asinhronih operacij pomemben. Razmislite o teh pogostih scenarijih:
- Navigacija uporabnika: Uporabnik sproži poizvedbo za iskanje, ki sproži zahtevo API. Če se hitro pomakne na drugo stran, preden se zahteva zaključi, postane prvotna zahteva nepomembna in jo je treba preklicati, da se izognete nepotrebnemu omrežnemu prometu in morebitnim stranskim učinkom.
- Upravljanje časovne omejitve: Nastavite časovno omejitev za asinhrono operacijo. Če se operacija zaključi pred potekom časovne omejitve, morate preklicati časovno omejitev, da preprečite odvečno izvajanje kode.
- Odstranjevanje komponente: V sprednjih ogrodjih, kot sta React ali Vue.js, komponente pogosto zahtevajo asinkrono. Ko se komponenta odstrani, je treba preklicati vse tekoče zahteve, povezane s to komponento, da se izognete uhajanju pomnilnika in napakam, ki jih povzroča posodabljanje odstranjenih komponent.
- Omejitve virov: V okoljih z omejenimi viri (npr. mobilne naprave, vgrajeni sistemi) lahko preklic nepotrebnih operacij sprosti dragocene vire in izboljša zmogljivost. Na primer, preklic prenosa velike slike, če se uporabnik pomakne mimo tega dela strani.
Predstavljamo AbortController in AbortSignal
Vmesnik AbortController
je zasnovan za reševanje problema preklica asinhronih operacij. Sestavljen je iz dveh ključnih komponent:
- AbortController: Ta objekt upravlja signal za preklic. Ima eno metodo,
abort()
, ki se uporablja za signaliziranje zahteve za preklic. - AbortSignal: Ta objekt predstavlja signal, da je treba operacijo prekiniti. Povezan je z
AbortController
in se posreduje asinhroni operaciji, ki jo je treba preklicati.
Osnovna uporaba: Preklic zahtev za pridobivanje
Začnimo s preprostim primerom preklica zahteve pridobivanje
:
const controller = new AbortController();
const signal = controller.signal;
fetch('https://api.example.com/data', { signal })
.then(response => {
if (!response.ok) {
throw new Error(`Napaka HTTP! Status: ${response.status}`);
}
return response.json();
})
.then(data => {
console.log('Podatki:', data);
})
.catch(error => {
if (error.name === 'AbortError') {
console.log('Pridobivanje prekinjeno');
} else {
console.error('Napaka pri pridobivanju:', error);
}
});
// Za preklic zahteve za pridobivanje:
controller.abort();
Pojasnilo:
- Ustvarimo instanco
AbortController
. - Iz
krmilnika
pridobimo povezanAbortSignal
. Signal
posredujemo možnostimpridobivanja
.- Če moramo zahtevo preklicati, pokličemo
controller.abort()
. - V bloku
.catch()
preverimo, ali je napakaAbortError
. Če je, vemo, da je bila zahteva preklicana.
Obravnava AbortError
Ko se pokliče controller.abort()
, bo zahteva pridobivanja
zavrnjena z AbortError
. Zelo pomembno je, da to napako ustrezno obravnavate v svoji kodi. Če tega ne storite, lahko pride do neobravnanih zavrnitev obljub in nepričakovanega vedenja.
Tukaj je bolj robusten primer z obravnavo napak:
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(`Napaka HTTP! Status: ${response.status}`);
}
const data = await response.json();
console.log('Podatki:', data);
return data;
} catch (error) {
if (error.name === 'AbortError') {
console.log('Pridobivanje prekinjeno');
return null; // Ali pa vrzi napako, ki jo je treba obravnavati višje
} else {
console.error('Napaka pri pridobivanju:', error);
throw error; // Ponovno vrzi napako, ki jo je treba obravnavati višje
}
}
}
fetchData();
// Za preklic zahteve za pridobivanje:
controller.abort();
Najboljše prakse za obravnavo AbortError:
- Preverite ime napake: Vedno preverite, ali je
error.name === 'AbortError'
, da zagotovite, da obravnavate pravilno vrsto napake. - Vrnite privzeto vrednost ali ponovno vrnite: Odvisno od logike vaše aplikacije boste morda želeli vrniti privzeto vrednost (npr.
null
) ali ponovno vrniti napako, ki jo je treba obravnavati višje v skladu klicev. - Očistite vire: Če je asinhrona operacija dodelila vire (npr. časovniki, poslušalci dogodkov), jih počistite v upravljavcu
AbortError
.
Preklic časovnikov s signalom AbortSignal
AbortSignal
se lahko uporabi tudi za preklic časovnikov, ustvarjenih z setTimeout
ali setInterval
. To zahteva malo več ročnega dela, saj vgrajene funkcije časovnika ne podpirajo neposredno AbortSignal
. Ustvariti morate funkcijo po meri, ki posluša signal za preklic in počisti časovnik, ko se sproži.
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('Časovna omejitev prekinjena'));
});
});
return timeoutPromise;
}
const controller = new AbortController();
const signal = controller.signal;
cancellableTimeout(() => {
console.log('Časovna omejitev izvršena');
}, 2000, signal)
.then(() => console.log("Časovna omejitev uspešno zaključena"))
.catch(err => console.log(err));
// Za preklic časovne omejitve:
controller.abort();
Pojasnilo:
- Funkcija
cancellableTimeout
sprejme povratni klic, zakasnitev inAbortSignal
kot argumente. - Nastavi
setTimeout
in shrani ID časovne omejitve. - Doda poslušalca dogodkov v
AbortSignal
, ki posluša dogodekpreklica
. - Ko se sproži dogodek
preklic
, poslušalec dogodkov počisti časovno omejitev in zavrne obljubo.
Preklic poslušalcev dogodkov
Podobno kot pri časovnikih lahko uporabite AbortSignal
za preklic poslušalcev dogodkov. To je še posebej uporabno, ko želite odstraniti poslušalce dogodkov, povezane s komponento, ki se odstranjuje.
const controller = new AbortController();
const signal = controller.signal;
const button = document.getElementById('myButton');
button.addEventListener('click', () => {
console.log('Gumb pritisnjen!');
}, { signal });
// Za preklic poslušalca dogodkov:
controller.abort();
Pojasnilo:
Signal
posredujemo kot možnost metodiaddEventListener
.- Ko se pokliče
controller.abort()
, bo poslušalec dogodkov samodejno odstranjen.
AbortController v React komponentah
V Reactu lahko uporabite AbortController
za preklic asinhronih operacij, ko se komponenta odstrani. To je bistveno za preprečevanje uhajanja pomnilnika in napak, ki jih povzroča posodabljanje odstranjenih komponent. Tukaj je primer z uporabo kljuke 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(`Napaka HTTP! Status: ${response.status}`);
}
const data = await response.json();
setData(data);
} catch (error) {
if (error.name === 'AbortError') {
console.log('Pridobivanje prekinjeno');
} else {
console.error('Napaka pri pridobivanju:', error);
}
}
}
fetchData();
return () => {
controller.abort(); // Prekliči zahtevo za pridobivanje, ko se komponenta odstrani
};
}, []); // Prazno polje odvisnosti zagotavlja, da se ta učinek izvede samo enkrat ob namestitvi
return (
{data ? (
Podatki: {JSON.stringify(data)}
) : (
Nalaganje...
)}
);
}
export default MyComponent;
Pojasnilo:
- Ustvarimo
AbortController
znotraj kljukeuseEffect
. Signal
posredujemo zahtevipridobivanja
.- Iz kljuke
useEffect
vrnemo funkcijo čiščenja. Ta funkcija bo poklicana, ko se komponenta odstrani. - Znotraj funkcije čiščenja pokličemo
controller.abort()
, da prekličemo zahtevo za pridobivanje.
Napredne uporabe
Veriženje signalov za preklic
Včasih boste morda želeli skupaj povezati več AbortSignal
. Na primer, morda imate nadrejeno komponento, ki mora preklicati operacije v svojih podrejenih komponentah. To lahko dosežete tako, da ustvarite nov AbortController
in njegov signal posredujete nadrejeni in podrejeni komponenti.
Uporaba AbortController s knjižnicami tretjih oseb
Če uporabljate knjižnico tretje osebe, ki ne podpira neposredno AbortSignal
, boste morda morali prilagoditi svojo kodo, da bo delovala z mehanizmom preklica knjižnice. To lahko vključuje zavijanje asinhronih funkcij knjižnice v svoje funkcije, ki obravnavajo AbortSignal
.
Prednosti uporabe AbortController
- Izboljšana zmogljivost: Preklic nepotrebnih operacij lahko zmanjša omrežni promet, uporabo CPE in porabo pomnilnika, kar vodi do izboljšane zmogljivosti, zlasti v napravah z omejenimi viri.
- Čistejša koda:
AbortController
omogoča standardiziran in eleganten način upravljanja preklica, zaradi česar je vaša koda bolj berljiva in vzdržljiva. - Preprečevanje uhajanja pomnilnika: Preklic asinhronih operacij, povezanih z odstranjenimi komponentami, preprečuje uhajanje pomnilnika in napake, ki jih povzroča posodabljanje odstranjenih komponent.
- Boljša uporabniška izkušnja: Preklic nepomembnih zahtev lahko izboljša uporabniško izkušnjo, tako da prepreči prikaz zastarelih informacij in zmanjša zaznano zakasnitev.
Združljivost brskalnika
AbortController
je široko podprt v sodobnih brskalnikih, vključno s Chrome, Firefox, Safari in Edge. Najnovejše informacije lahko preverite v tabeli združljivosti na spletnem mestu MDN Web Docs.
Polifili
Za starejše brskalnike, ki izvorno ne podpirajo AbortController
, lahko uporabite polifil. Polifil je kos kode, ki zagotavlja funkcionalnost novejše funkcije v starejših brskalnikih. Na spletu je na voljo več polifilov AbortController
.
Zaključek
Vmesnik AbortController
je zmogljivo orodje za upravljanje asinhronih operacij v JavaScriptu. Z uporabo AbortController
lahko napišete čistejšo, zmogljivejšo in bolj robustno kodo, ki učinkovito obravnava preklic. Ne glede na to, ali pridobivate podatke iz API-jev, nastavljate časovnike ali upravljate poslušalce dogodkov, vam lahko AbortController
pomaga izboljšati splošno kakovost vaših spletnih aplikacij.