Išsamus „JavaScript“ AbortController API vadovas, apimantis užklausų atšaukimą, išteklių valdymą, klaidų tvarkymą ir pažangius naudojimo atvejus moderniai žiniatinklio plėtrai.
AbortController API: Užklausų atšaukimo ir išteklių valdymo įsisavinimas
Šiuolaikinėje žiniatinklio plėtroje efektyvus asinchroninių operacijų valdymas yra gyvybiškai svarbus kuriant reaguojančias ir našias programas. AbortController API suteikia galingą mechanizmą užklausoms atšaukti ir ištekliams valdyti, užtikrinant geresnę vartotojo patirtį ir išvengiant nereikalingų pridėtinių išlaidų. Šiame išsamiame vadove detaliai nagrinėjama AbortController API, apimanti pagrindines sąvokas, praktinius naudojimo atvejus ir pažangias technikas.
Kas yra AbortController API?
AbortController API yra integruotas JavaScript API, leidžiantis atšaukti vieną ar daugiau žiniatinklio užklausų. Jį sudaro du pagrindiniai komponentai:
- AbortController: Valdiklio objektas, kuris inicijuoja atšaukimo procesą.
- AbortSignal: Signalo objektas, susietas su AbortController, kuris perduodamas asinchroninei operacijai (pvz.,
fetch
užklausai), kad būtų klausomasi atšaukimo signalų.
Kai AbortController
objekte iškviečiamas abort()
metodas, susietas AbortSignal
išsiunčia abort
įvykį, kurio asinchroninė operacija gali klausytis ir atitinkamai reaguoti. Tai leidžia sklandžiai atšaukti užklausas, išvengiant nereikalingo duomenų perdavimo ir apdorojimo.
Pagrindinės sąvokos
1. AbortController kūrimas
Norėdami naudoti AbortController API, pirmiausia turite sukurti AbortController
klasės egzempliorių:
const controller = new AbortController();
2. AbortSignal gavimas
AbortController
egzempliorius suteikia prieigą prie AbortSignal
objekto per savo signal
savybę:
const signal = controller.signal;
3. AbortSignal perdavimas asinchroninei operacijai
AbortSignal
tada perduodamas kaip parinktis asinchroninei operacijai, kurią norite valdyti. Pavyzdžiui, naudojant fetch
API, galite perduoti signal
kaip parinkčių objekto dalį:
fetch('/api/data', { signal })
.then(response => response.json())
.then(data => {
console.log('Duomenys gauti:', data);
})
.catch(error => {
if (error.name === 'AbortError') {
console.log('Užklausa atšaukta');
} else {
console.error('Užklausos klaida:', error);
}
});
4. Užklausos atšaukimas
Norėdami atšaukti užklausą, iškvieskite abort()
metodą AbortController
egzemplioriuje:
controller.abort();
Tai suaktyvins abort
įvykį susietame AbortSignal
, dėl kurio fetch
užklausa bus atmesta su AbortError
.
Praktiniai naudojimo atvejai
1. Fetch užklausų atšaukimas
Vienas iš dažniausių AbortController API naudojimo atvejų yra fetch
užklausų atšaukimas. Tai ypač naudinga scenarijuose, kai vartotojas išeina iš puslapio arba atlieka veiksmą, dėl kurio vykdoma užklausa tampa nebereikalinga. Įsivaizduokite scenarijų, kai vartotojas ieško produktų el. prekybos svetainėje. Jei vartotojas įveda naują paieškos užklausą prieš baigiant vykdyti ankstesnę, AbortController gali būti naudojamas ankstesnei užklausai atšaukti, taip taupant pralaidumą ir apdorojimo galią.
let controller = null;
function searchProducts(query) {
if (controller) {
controller.abort();
}
controller = new AbortController();
const signal = controller.signal;
fetch(`/api/products?q=${query}`, { signal })
.then(response => response.json())
.then(products => {
displayProducts(products);
})
.catch(error => {
if (error.name === 'AbortError') {
console.log('Paieška atšaukta');
} else {
console.error('Paieškos klaida:', error);
}
});
}
function displayProducts(products) {
// Parodykite produktus vartotojo sąsajoje
console.log('Produktai:', products);
}
// Naudojimo pavyzdys:
searchProducts('batai');
searchProducts('marškinėliai'); // Atšaukia ankstesnę paiešką „batai“
2. Laiko limitų (timeouts) įgyvendinimas
AbortController API taip pat gali būti naudojamas įgyvendinti laiko limitus asinchroninėms operacijoms. Tai užtikrina, kad užklausos nepakibs neribotam laikui, jei serveris nereaguoja. Tai svarbu paskirstytose sistemose, kur tinklo delsos ar serverio problemos gali sukelti ilgesnį nei tikėtasi užklausų vykdymą. Nustatant laiko limitą galima išvengti, kad programa įstrigtų laukdama atsakymo, kuris gali niekada neateiti.
async function fetchDataWithTimeout(url, timeout) {
const controller = new AbortController();
const signal = controller.signal;
const timeoutId = setTimeout(() => {
controller.abort();
}, timeout);
try {
const response = await fetch(url, { signal });
clearTimeout(timeoutId);
return await response.json();
} catch (error) {
clearTimeout(timeoutId);
if (error.name === 'AbortError') {
throw new Error('Užklausos laikas baigėsi');
} else {
throw error;
}
}
}
// Naudojimo pavyzdys:
fetchDataWithTimeout('/api/data', 5000) // 5 sekundžių laiko limitas
.then(data => {
console.log('Duomenys gauti:', data);
})
.catch(error => {
console.error('Klaida:', error.message);
});
3. Kelių asinchroninių operacijų valdymas
AbortController API gali būti naudojamas valdyti kelias asinchronines operacijas vienu metu. Tai naudinga scenarijuose, kai reikia atšaukti susijusių užklausų grupę. Pavyzdžiui, įsivaizduokite prietaisų skydelio programą, kuri gauna duomenis iš kelių šaltinių. Jei vartotojas išeina iš prietaisų skydelio, visos laukiančios užklausos turėtų būti atšauktos, kad būtų atlaisvinti ištekliai.
const controller = new AbortController();
const signal = controller.signal;
const urls = [
'/api/data1',
'/api/data2',
'/api/data3'
];
async function fetchData(url) {
try {
const response = await fetch(url, { signal });
return await response.json();
} catch (error) {
if (error.name === 'AbortError') {
console.log(`Užklausa atšaukta ${url}`);
} else {
console.error(`Užklausos klaida ${url}:`, error);
}
throw error;
}
}
Promise.all(urls.map(fetchData))
.then(results => {
console.log('Visi duomenys gauti:', results);
})
.catch(error => {
console.error('Klaida gaunant duomenis:', error);
});
// Norėdami atšaukti visas užklausas:
controller.abort();
Pažangios technikos
1. AbortController naudojimas su įvykių klausytojais (Event Listeners)
AbortController API taip pat gali būti naudojamas valdyti įvykių klausytojus. Tai naudinga norint išvalyti įvykių klausytojus, kai komponentas yra išmontuojamas arba įvyksta konkretus įvykis. Pavyzdžiui, kuriant pasirinktinį vaizdo grotuvą, galbūt norėsite pridėti įvykių klausytojus 'play', 'pause' ir 'ended' įvykiams. Naudojant AbortController užtikrinama, kad šie klausytojai bus tinkamai pašalinti, kai grotuvas nebebus reikalingas, taip išvengiant atminties nutekėjimo.
function addEventListenerWithAbort(element, eventType, listener, signal) {
element.addEventListener(eventType, listener);
signal.addEventListener('abort', () => {
element.removeEventListener(eventType, listener);
});
}
// Naudojimo pavyzdys:
const controller = new AbortController();
const signal = controller.signal;
const button = document.getElementById('myButton');
function handleClick() {
console.log('Mygtukas paspaustas!');
}
addEventListenerWithAbort(button, 'click', handleClick, signal);
// Norėdami pašalinti įvykio klausytoją:
controller.abort();
2. AbortSignal signalų sujungimas
Kai kuriais atvejais gali prireikti sujungti kelis AbortSignal signalus. Tai leidžia sukurti atšaukimo signalų hierarchiją, kur vieno signalo atšaukimas automatiškai atšaukia visus jo pavaldžius signalus. Tai galima pasiekti sukuriant pagalbinę funkciją, kuri sujungia kelis signalus į vieną. Įsivaizduokite sudėtingą darbo eigą, kur keli komponentai priklauso vienas nuo kito. Jei vienas komponentas sugenda arba yra atšaukiamas, galbūt norėsite automatiškai atšaukti visus priklausomus komponentus.
function combineAbortSignals(...signals) {
const controller = new AbortController();
signals.forEach(signal => {
if (signal) {
signal.addEventListener('abort', () => {
controller.abort();
});
}
});
return controller.signal;
}
// Naudojimo pavyzdys:
const controller1 = new AbortController();
const controller2 = new AbortController();
const combinedSignal = combineAbortSignals(controller1.signal, controller2.signal);
fetch('/api/data', { signal: combinedSignal })
.then(response => response.json())
.then(data => {
console.log('Duomenys gauti:', data);
})
.catch(error => {
if (error.name === 'AbortError') {
console.log('Užklausa atšaukta');
} else {
console.error('Užklausos klaida:', error);
}
});
// Atšaukus controller1, bus atšaukta ir fetch užklausa:
controller1.abort();
3. AbortError klaidų tvarkymas globaliai
Siekiant pagerinti kodo palaikymą, galite sukurti globalų klaidų tvarkytoją, kad pagautumėte ir tvarkytumėte AbortError
išimtis. Tai gali supaprastinti klaidų tvarkymą jūsų programoje ir užtikrinti nuoseklų elgesį. Tai galima padaryti sukuriant pasirinktinę klaidų tvarkymo funkciją, kuri tikrina AbortError klaidas ir imasi atitinkamų veiksmų. Šis centralizuotas požiūris palengvina klaidų tvarkymo logikos atnaujinimą ir užtikrina nuoseklumą visoje programoje.
function handleAbortError(error) {
if (error.name === 'AbortError') {
console.log('Užklausa atšaukta globaliai');
// Atlikite reikalingus valymo ar UI atnaujinimo veiksmus
}
}
// Naudojimo pavyzdys:
fetch('/api/data')
.then(response => response.json())
.then(data => {
console.log('Duomenys gauti:', data);
})
.catch(error => {
handleAbortError(error);
console.error('Užklausos klaida:', error);
});
Klaidų tvarkymas
Kai užklausa atšaukiama naudojant AbortController API, fetch
pažadas (promise) atmetamas su AbortError
. Svarbu tinkamai tvarkyti šią klaidą, kad išvengtumėte netikėto elgesio jūsų programoje.
fetch('/api/data', { signal })
.then(response => response.json())
.then(data => {
console.log('Duomenys gauti:', data);
})
.catch(error => {
if (error.name === 'AbortError') {
console.log('Užklausa atšaukta');
// Atlikite reikalingus valymo ar UI atnaujinimo veiksmus
} else {
console.error('Užklausos klaida:', error);
// Tvarkykite kitas klaidas
}
});
Klaidų tvarkymo bloke galite patikrinti AbortError
, išnagrinėję error.name
savybę. Jei klaida yra AbortError
, galite atlikti reikalingus valymo ar UI atnaujinimo veiksmus, pavyzdžiui, parodyti pranešimą vartotojui arba atstatyti programos būseną.
Geriausios praktikos
- Visada tvarkykite
AbortError
išimtis: Užtikrinkite, kad jūsų kodas sklandžiai tvarkytųAbortError
išimtis, kad išvengtumėte netikėto elgesio. - Naudokite aprašomuosius klaidų pranešimus: Pateikite aiškius ir informatyvius klaidų pranešimus, kad padėtumėte kūrėjams derinti ir spręsti problemas.
- Išvalykite išteklius: Kai užklausa atšaukiama, išvalykite visus susijusius išteklius, tokius kaip laikmačiai ar įvykių klausytojai, kad išvengtumėte atminties nutekėjimo.
- Apsvarstykite laiko limitų vertes: Nustatykite tinkamas laiko limitų vertes asinchroninėms operacijoms, kad užklausos nepakibtų neribotam laikui.
- Naudokite AbortController ilgai trunkančioms operacijoms: Operacijoms, kurios gali užtrukti ilgai, naudokite AbortController API, kad leistumėte vartotojams prireikus atšaukti operaciją.
Naršyklių suderinamumas
AbortController API yra plačiai palaikomas moderniose naršyklėse, įskaitant Chrome, Firefox, Safari ir Edge. Tačiau senesnės naršyklės gali nepalaikyti šio API. Siekiant užtikrinti suderinamumą su senesnėmis naršyklėmis, galite naudoti polifilą (polyfill). Yra keletas prieinamų polifilų, kurie suteikia AbortController funkcionalumą senesnėms naršyklėms. Šiuos polifilus galima lengvai integruoti į savo projektą naudojant paketų tvarkykles, tokias kaip npm ar yarn.
AbortController ateitis
AbortController API yra besivystanti technologija, ir ateities specifikacijos versijos gali pristatyti naujų funkcijų bei patobulinimų. Svarbu sekti naujausius AbortController API pokyčius, norint kurti modernias ir efektyvias žiniatinklio programas. Stebėkite naršyklių atnaujinimus ir JavaScript standartus, kad galėtumėte pasinaudoti naujomis galimybėmis, kai jos taps prieinamos.
Išvada
AbortController API yra vertingas įrankis valdant asinchronines operacijas JavaScript. By providing a mechanism for canceling requests and managing resources, it enables developers to build more responsive, performant, and user-friendly web applications. Suprasti pagrindines AbortController API sąvokas, praktinius naudojimo atvejus ir pažangias technikas yra būtina šiuolaikinei žiniatinklio plėtrai. Įsisavinę šį API, kūrėjai gali kurti tvirtas ir efektyvias programas, kurios suteikia geresnę vartotojo patirtį.