JavaScript'da Event Loop
JavaScript'da Event Loop - bu tilning asinxron va noblock qiluvchi xususiyatlarini ta'minlaydigan asosiy mexanizmidir.
So'nggi yangilanish: 2024-12-14JavaScript'ning Event Loop (Hodisalar Halqasi) - bu tilning asinxron va noblock qiluvchi xususiyatlarini ta'minlaydigan asosiy mexanizmdir. U JavaScript'ning bir oqimli bo'lishiga qaramay, ko'p vazifali operatsiyalarni bajarish imkonini beradi. Ushbu qo'llanma Event Loop'ning ishlashi, uning komponentlari va JavaScript dasturlashdagi ahamiyatini tushuntirishga qaratilgan.
Event Loop Nima?
Event Loop - bu JavaScript'ning asinxron operatsiyalarni boshqarish mexanizmi. U Call Stack, Callback Queue va Web API'lar o'rtasidagi o'zaro ta'sirni muvofiqlashtiradi, bu esa JavaScript'ga bir vaqtning o'zida ko'p vazifalarni bajarish imkonini beradi.
JavaScript'ning Bir Oqimliligi
JavaScript bir oqimli tildir, ya'ni u bir vaqtning o'zida faqat bitta vazifani bajarishi mumkin. Ammo Event Loop tufayli, u ko'p vazifali bo'lib ko'rinadi.
console.log("Birinchi");
setTimeout(() => console.log("Ikkinchi"), 0);
console.log("Uchinchi");
// Natija:
// Birinchi
// Uchinchi
// Ikkinchi
Bu misolda, "Ikkinchi" so'zi oxirida chop etiladi, chunki setTimeout
Web API'ga o'tkaziladi va keyingi kod bajarilishda davom etadi.
Call Stack (Chaqiruvlar To'plami)
Call Stack - bu JavaScript interpretatori funksiyalarni bajarish uchun foydalananadigan ma'lumotlar tuzilmasi. U LIFO (Last In, First Out) prinsipi asosida ishlaydi.
function birinchiFunksiya() {
ikkinchiFunksiya();
console.log("Birinchi");
}
function ikkinchiFunksiya() {
console.log("Ikkinchi");
}
birinchiFunksiya();
// Natija:
// Ikkinchi
// Birinchi
Callback Queue (Qayta Chaqiruv Navbati)
Callback Queue - bu Web API'lardan qaytarilgan qayta chaqiruvlar (callbacks) saqlanadigan joy. Event Loop ularni Call Stack bo'shaganda bajaradi.
console.log("Boshlandi");
setTimeout(() => {
console.log("Timeout bajarildi");
}, 0);
console.log("Tugadi");
// Natija:
// Boshlandi
// Tugadi
// Timeout bajarildi
Web API'lar
Web API'lar brauzer tomonidan taqdim etilgan funksiyalardir. Ular setTimeout
, fetch
, DOM hodisalari kabi asinxron operatsiyalarni bajaradi.
console.log("Boshlandi");
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log("Ma'lumotlar olindi:", data))
.catch(error => console.error("Xato:", error));
console.log("So'rov yuborildi");
// Natija:
// Boshlandi
// So'rov yuborildi
// Ma'lumotlar olindi: [olingan ma'lumotlar] (yoki Xato: [xato ma'lumoti])
Event Loop'ning Ishlash Jarayoni
- Call Stack'dagi barcha vazifalarni bajarish.
- Mikrotasklarni bajarish (Promise'lar, qatorlar).
- Makrotasklarni bajarish (setTimeout, setInterval, I/O).
- Agar Call Stack bo'sh bo'lsa, Callback Queue'dan navbatdagi vazifani olish.
- Jarayonni takrorlash.
Makrotasklar va Mikrotasklar
Makrotasklar: setTimeout, setInterval, setImmediate, I/O operatsiyalari. Mikrotasklar: Promise'lar, qatorlar, Object.observe, MutationObserver.
console.log("Script boshlandi");
setTimeout(() => console.log("Timeout"), 0);
Promise.resolve().then(() => console.log("Promise"));
console.log("Script tugadi");
// Natija:
// Script boshlandi
// Script tugadi
// Promise
// Timeout
Asinxron Dasturlash va Event Loop
Event Loop asinxron dasturlashning asosiy qismidir. U callback'lar, Promise'lar va async/await kabi asinxron patternlarni qo'llab-quvvatlaydi.
async function ma'lumotOlish() {
console.log("Funksiya boshlandi");
const javob = await fetch('https://api.example.com/data');
const ma'lumot = await javob.json();
console.log("Ma'lumot olindi:", ma'lumot);
console.log("Funksiya tugadi");
}
console.log("Script boshlandi");
ma'lumotOlish();
console.log("Script tugadi");
// Natija:
// Script boshlandi
// Funksiya boshlandi
// Script tugadi
// Ma'lumot olindi: [olingan ma'lumotlar]
// Funksiya tugadi
Amaliy Misollar
- Oddiy Timer:
function timer(sekund) {
console.log(`Timer boshlandi: ${sekund} sekund`);
const intervalId = setInterval(() => {
sekund--;
console.log(`Qolgan vaqt: ${sekund} sekund`);
if (sekund === 0) {
clearInterval(intervalId);
console.log("Timer tugadi!");
}
}, 1000);
}
timer(5);
- Ketma-ket Asinxron Operatsiyalar:
function kechiktir(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function ketmaKetVazifalar() {
console.log("Boshlandi");
await kechiktir(2000);
console.log("2 soniyadan so'ng");
await kechiktir(1000);
console.log("Yana 1 soniyadan so'ng");
await kechiktir(1500);
console.log("Yana 1.5 soniyadan so'ng");
console.log("Tugadi");
}
ketmaKetVazifalar();
Keng Tarqalgan Xatolar va Ularning Yechimlari
- Bloklash Xatosi:
// Xato
function uzunVazifa() {
for (let i = 0; i < 1000000000; i++) {
// Uzoq hisob-kitob
}
}
uzunVazifa();
console.log("Bu tezda chop etilmaydi");
// To'g'ri yechim
function uzunVazifa() {
return new Promise(resolve => {
setTimeout(() => {
for (let i = 0; i < 1000000000; i++) {
// Uzoq hisob-kitob
}
resolve();
}, 0);
});
}
uzunVazifa().then(() => console.log("Vazifa tugadi"));
console.log("Bu darhol chop etiladi");
- Asinxron Operatsiyalarni Noto'g'ri Boshqarish:
// Xato
function ma'lumotOlish() {
let ma'lumot;
fetch('https://api.example.com/data')
.then(javob => javob.json())
.then(natija => {
ma'lumot = natija;
});
return ma'lumot; // Bu undefined qaytaradi
}
// To'g'ri yechim
async function ma'lumotOlish() {
const javob = await fetch('https://api.example.com/data');
const ma'lumot = await javob.json();
return ma'lumot;
}
ma'lumotOlish().then(ma'lumot => console.log(ma'lumot));
Ishlash Samaradorligi Mulohazalari
- Og'ir hisob-kitoblarni Web Worker'larga o'tkazing.
- Mikrotasklar (Promise'lar) makrotasklardan (setTimeout) oldin bajarilishini yodda tuting.
- Chuqur o'rnatilgan qayta chaqiruvlardan (callback hell) qoching.
- Katta tsikllar uchun
requestAnimationFrame
yokisetTimeout
dan foydalaning.
Event Loop va Zamonaviy JavaScript
Zamonaviy JavaScript kutubxonalari va freymvorklari (React, Vue, Angular) Event Loop'dan foydalanib, samarali va silliq foydalanuvchi interfeyslarini yaratadi.
// React komponenti misoli
function MeningKomponentim() {
const [sanoq, sanoqniO'zgartir] = useState(0);
useEffect(() => {
const intervalId = setInterval(() => {
sanoqniO'zgartir(oldingiSanoq => oldingiSanoq + 1);
}, 1000);
return () => clearInterval(intervalId);
}, []);
return <div>Sanoq: {sanoq}</div>;
}
Tez-tez So'raladigan Savollar
- Savol: Event Loop qanday ishlaydi? Javob: Event Loop doimiy ravishda Call Stack'ni tekshiradi. Agar u bo'sh bo'lsa, Callback Queue'dan navbatdagi vazifani oladi va uni Call Stack'ga qo'yadi.
- Savol: Promise'lar va setTimeout o'rtasidagi farq nima? Javob: Promise'lar mikrotasklardir va setTimeout kabi makrotasklardan oldin bajariladi.
- Savol: Node.js'da Event Loop qanday ishlaydi? Javob: Node.js'dagi Event Loop brauzernikiga o'xshash, lekin u qo'shimcha bosqichlarni o'z ichiga oladi, masalan, I/O operatsiyalari uchun.