JavaScript AbortController-dan foydalanib, fetch so'rovlari, taymerlar va boshqa asinxron operatsiyalarni samarali bekor qilishni o'rganing, bu esa toza va unumdor kodni ta'minlaydi.
JavaScript AbortController: Asinxron operatsiyalarni bekor qilishni o'zlashtirish
Zamonaviy veb-dasturlashda asinxron operatsiyalar hamma joyda mavjud. API'lardan ma'lumotlarni olish, taymerlarni o'rnatish va foydalanuvchi bilan o'zaro aloqalarni boshqarish ko'pincha mustaqil va uzoq vaqt davomida ishlashi mumkin bo'lgan kodni o'z ichiga oladi. Biroq, bu operatsiyalarni ular tugashidan oldin bekor qilish kerak bo'lgan holatlar mavjud. Aynan shu yerda JavaScript'dagi AbortController
interfeysi yordamga keladi. U DOM operatsiyalari va boshqa asinxron vazifalarga bekor qilish so'rovlarini signal qilishning toza va samarali usulini taqdim etadi.
Bekor qilish zaruratini tushunish
Texnik tafsilotlarga sho'ng'ishdan oldin, asinxron operatsiyalarni bekor qilish nima uchun muhimligini tushunib olaylik. Ushbu keng tarqalgan holatlarni ko'rib chiqing:
- Foydalanuvchi navigatsiyasi: Foydalanuvchi qidiruv so'rovini boshlaydi, bu esa API so'rovini ishga tushiradi. Agar ular so'rov tugashidan oldin tezda boshqa sahifaga o'tishsa, asl so'rov ahamiyatsiz bo'lib qoladi va keraksiz tarmoq trafigi hamda yuzaga kelishi mumkin bo'lgan yon ta'sirlarning oldini olish uchun bekor qilinishi kerak.
- Taymoutni boshqarish: Siz asinxron operatsiya uchun taymout o'rnatasiz. Agar operatsiya taymout tugashidan oldin yakunlansa, ortiqcha kod bajarilishining oldini olish uchun taymoutni bekor qilishingiz kerak.
- Komponentni o'chirish (Unmounting): React yoki Vue.js kabi front-end freymvorklarida komponentlar ko'pincha asinxron so'rovlar yuboradi. Komponent o'chirilganda, u bilan bog'liq bo'lgan har qanday davom etayotgan so'rovlar xotira sizib chiqishining va o'chirilgan komponentlarni yangilash natijasida yuzaga keladigan xatoliklarning oldini olish uchun bekor qilinishi kerak.
- Resurs cheklovlari: Resurslari cheklangan muhitlarda (masalan, mobil qurilmalar, o'rnatilgan tizimlar) keraksiz operatsiyalarni bekor qilish qimmatli resurslarni bo'shatishi va unumdorlikni oshirishi mumkin. Masalan, agar foydalanuvchi sahifaning o'sha qismidan o'tib ketsa, katta hajmdagi rasmni yuklab olishni bekor qilish.
AbortController va AbortSignal bilan tanishuv
AbortController
interfeysi asinxron operatsiyalarni bekor qilish muammosini hal qilish uchun mo'ljallangan. U ikkita asosiy komponentdan iborat:
- AbortController: Ushbu obyekt bekor qilish signalini boshqaradi. Uning yagona
abort()
metodi mavjud bo'lib, u bekor qilish so'rovini signal qilish uchun ishlatiladi. - AbortSignal: Ushbu obyekt operatsiyani bekor qilish kerakligi haqidagi signalni ifodalaydi. U
AbortController
bilan bog'langan va bekor qilinishi kerak bo'lgan asinxron operatsiyaga uzatiladi.
Asosiy foydalanish: Fetch so'rovlarini bekor qilish
Keling, fetch
so'rovini bekor qilishning oddiy misolidan boshlaylik:
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();
Tushuntirish:
- Biz
AbortController
obyektini yaratamiz. - Biz
controller
'dan bog'liqAbortSignal
ni olamiz. - Biz
signal
nifetch
parametrlariga uzatamiz. - Agar so'rovni bekor qilishimiz kerak bo'lsa,
controller.abort()
ni chaqiramiz. .catch()
blokida xatoningAbortError
ekanligini tekshiramiz. Agar shunday bo'lsa, so'rov bekor qilinganini bilamiz.
AbortError xatoligini qayta ishlash
controller.abort()
chaqirilganda, fetch
so'rovi AbortError
bilan rad etiladi. Kodingizda bu xatolikni to'g'ri qayta ishlash juda muhim. Buni e'tiborsiz qoldirish, qayta ishlanmagan promise'larning rad etilishiga va kutilmagan xatti-harakatlarga olib kelishi mumkin.
Bu yerda xatoliklarni qayta ishlash bilan yanada mustahkamroq misol keltirilgan:
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; // Yoki xatolikni yuqoriroq darajada qayta ishlash uchun yuborish
} else {
console.error('Fetch error:', error);
throw error; // Xatolikni yuqoriroq darajada qayta ishlash uchun qayta yuborish
}
}
}
fetchData();
// To cancel the fetch request:
controller.abort();
AbortError bilan ishlash bo'yicha eng yaxshi amaliyotlar:
- Xato nomini tekshiring: To'g'ri xato turini qayta ishlayotganingizga ishonch hosil qilish uchun har doim
error.name === 'AbortError'
ekanligini tekshiring. - Standart qiymat qaytaring yoki xatoni qayta yuboring: Ilovangiz mantig'iga qarab, siz standart qiymat (masalan,
null
) qaytarishingiz yoki xatolikni chaqiruvlar zanjirida yuqoriroq darajada qayta ishlash uchun qayta yuborishingiz mumkin. - Resurslarni tozalang: Agar asinxron operatsiya biron bir resurs (masalan, taymerlar, hodisa tinglovchilari) ajratgan bo'lsa, ularni
AbortError
qayta ishlovchisida tozalang.
AbortSignal yordamida taymerlarni bekor qilish
AbortSignal
shuningdek, setTimeout
yoki setInterval
bilan yaratilgan taymerlarni bekor qilish uchun ham ishlatilishi mumkin. Bu biroz ko'proq qo'l mehnatini talab qiladi, chunki o'rnatilgan taymer funksiyalari to'g'ridan-to'g'ri AbortSignal
ni qo'llab-quvvatlamaydi. Siz bekor qilish signalini tinglaydigan va u ishga tushganda taymerni tozalaydigan maxsus funksiya yaratishingiz kerak.
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();
Tushuntirish:
cancellableTimeout
funksiyasi argument sifatida callback, kechikish vaAbortSignal
ni qabul qiladi.- U
setTimeout
o'rnatadi va taymer ID'sini saqlaydi. - U
AbortSignal
gaabort
hodisasini tinglaydigan hodisa tinglovchisini qo'shadi. abort
hodisasi ishga tushganda, hodisa tinglovchisi taymerni tozalaydi va promise'ni rad etadi.
Hodisa tinglovchilarni bekor qilish
Taymerlarga o'xshab, siz hodisa tinglovchilarni bekor qilish uchun AbortSignal
dan foydalanishingiz mumkin. Bu, ayniqsa, o'chirilayotgan komponent bilan bog'liq hodisa tinglovchilarni olib tashlashni xohlaganingizda foydalidir.
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();
Tushuntirish:
- Biz
signal
niaddEventListener
metodiga parametr sifatida uzatamiz. controller.abort()
chaqirilganda, hodisa tinglovchisi avtomatik ravishda olib tashlanadi.
React komponentlarida AbortController
React'da siz komponent o'chirilganda (unmount) asinxron operatsiyalarni bekor qilish uchun AbortController
dan foydalanishingiz mumkin. Bu xotira sizib chiqishining va o'chirilgan komponentlarni yangilash natijasida yuzaga keladigan xatoliklarning oldini olish uchun juda muhimdir. Mana useEffect
hookidan foydalanishga misol:
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(); // Komponent o'chirilganda fetch so'rovini bekor qilish
};
}, []); // Bo'sh bog'liqliklar massivi ushbu effekt faqat bir marta o'rnatilganda ishlashini ta'minlaydi
return (
{data ? (
Data: {JSON.stringify(data)}
) : (
Loading...
)}
);
}
export default MyComponent;
Tushuntirish:
- Biz
useEffect
hook ichidaAbortController
yaratamiz. - Biz
signal
nifetch
so'roviga uzatamiz. - Biz
useEffect
hookidan tozalash funksiyasini qaytaramiz. Bu funksiya komponent o'chirilganda chaqiriladi. - Tozalash funksiyasi ichida biz fetch so'rovini bekor qilish uchun
controller.abort()
ni chaqiramiz.
Ilg'or foydalanish holatlari
AbortSignal'larni zanjirlash
Ba'zan siz bir nechta AbortSignal
ni bir-biriga zanjir qilishni xohlashingiz mumkin. Masalan, sizda ota-komponent bo'lishi mumkin, u o'zining bola komponentlaridagi operatsiyalarni bekor qilishi kerak. Bunga yangi AbortController
yaratib, uning signalini ham ota, ham bola komponentlarga uzatish orqali erishishingiz mumkin.
Uchinchi tomon kutubxonalari bilan AbortController'dan foydalanish
Agar siz AbortSignal
ni to'g'ridan-to'g'ri qo'llab-quvvatlamaydigan uchinchi tomon kutubxonasidan foydalanayotgan bo'lsangiz, kodingizni kutubxonaning bekor qilish mexanizmi bilan ishlashga moslashtirishingiz kerak bo'lishi mumkin. Bu kutubxonaning asinxron funksiyalarini AbortSignal
ni boshqaradigan o'zingizning funksiyalaringizga o'rashni o'z ichiga olishi mumkin.
AbortController'dan foydalanishning afzalliklari
- Yaxshilangan unumdorlik: Keraksiz operatsiyalarni bekor qilish tarmoq trafigini, CPUdan foydalanishni va xotira iste'molini kamaytirishi mumkin, bu esa, ayniqsa, resurslari cheklangan qurilmalarda unumdorlikni oshirishga olib keladi.
- Tozaroq kod:
AbortController
bekor qilishni boshqarishning standartlashtirilgan va nafis usulini taqdim etadi, bu esa kodingizni o'qilishi oson va qo'llab-quvvatlanadigan qiladi. - Xotira sizib chiqishining oldini olish: O'chirilgan komponentlar bilan bog'liq asinxron operatsiyalarni bekor qilish xotira sizib chiqishining va o'chirilgan komponentlarni yangilash natijasida yuzaga keladigan xatoliklarning oldini oladi.
- Yaxshiroq foydalanuvchi tajribasi: Tegishli bo'lmagan so'rovlarni bekor qilish eskirgan ma'lumotlarning ko'rsatilishini oldini olish va seziladigan kechikishni kamaytirish orqali foydalanuvchi tajribasini yaxshilashi mumkin.
Brauzer mosligi
AbortController
zamonaviy brauzerlarda, jumladan Chrome, Firefox, Safari va Edge'da keng qo'llab-quvvatlanadi. Eng so'nggi ma'lumotlar uchun MDN Web Docs saytidagi moslik jadvalini tekshirishingiz mumkin.
Polifillar
AbortController
ni tabiiy ravishda qo'llab-quvvatlamaydigan eski brauzerlar uchun siz polifildan foydalanishingiz mumkin. Polifil - bu eski brauzerlarda yangi funksiyaning imkoniyatlarini ta'minlaydigan kod qismidir. Onlaynda bir nechta AbortController
polifillari mavjud.
Xulosa
AbortController
interfeysi JavaScript'dagi asinxron operatsiyalarni boshqarish uchun kuchli vositadir. AbortController
dan foydalanib, siz bekor qilishni osonlikcha boshqaradigan toza, unumdor va mustahkam kod yozishingiz mumkin. API'lardan ma'lumotlarni olyapsizmi, taymerlarni o'rnatyapsizmi yoki hodisa tinglovchilarni boshqaryapsizmi, AbortController
veb-ilovalaringizning umumiy sifatini yaxshilashga yordam beradi.