JavaScript'da Event Loop

JavaScript'da Event Loop - bu tilning asinxron va noblock qiluvchi xususiyatlarini ta'minlaydigan asosiy mexanizmidir.

So'nggi yangilanish: 2024-12-14

JavaScript'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

  1. Call Stack'dagi barcha vazifalarni bajarish.
  2. Mikrotasklarni bajarish (Promise'lar, qatorlar).
  3. Makrotasklarni bajarish (setTimeout, setInterval, I/O).
  4. Agar Call Stack bo'sh bo'lsa, Callback Queue'dan navbatdagi vazifani olish.
  5. 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

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

  1. 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");
  1. 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

  1. Og'ir hisob-kitoblarni Web Worker'larga o'tkazing.
  2. Mikrotasklar (Promise'lar) makrotasklardan (setTimeout) oldin bajarilishini yodda tuting.
  3. Chuqur o'rnatilgan qayta chaqiruvlardan (callback hell) qoching.
  4. Katta tsikllar uchun requestAnimationFrame yoki setTimeoutdan 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

  1. 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.
  2. Savol: Promise'lar va setTimeout o'rtasidagi farq nima? Javob: Promise'lar mikrotasklardir va setTimeout kabi makrotasklardan oldin bajariladi.
  3. 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.

Qo'shimcha Manbalar

  1. MDN: Asinxron dasturlash
  2. JavaScript.info: Event Loop
  3. Node.js Event Loop, Timers, and process.nextTick()
  4. Philip Roberts: Event Loop tushuntirilishi