# JavaScript event loop va navbat tizimi

> Event loop qanday ishlaydi: call stack, makrotask va mikrotask navbatlari, setTimeout va Promise tartibi, bir oqimli til va bloklanish muammosi.

Manba: https://learncode.uz/javascript/event-loop/
Sana: 2026-06-07

Nega `setTimeout(..., 0)` darhol bajarilmaydi? Nega `Promise` `setTimeout` dan
oldin chiqadi? Javob **event loop** da — JavaScript'ning ishlarni navbatga
qo'yish tizimida.

## JavaScript bir oqimli

```js
console.log("Boshlandi");

const startTime = Date.now();
while (Date.now() - startTime < 300) {
  // 300 ms davomida band
}

console.log("Tugadi:", Date.now() - startTime, "ms");
```

> **Atama**
>
> **Bir oqimli** (single-threaded) — JavaScript bir vaqtda faqat **bitta** ishni
> bajaradi. Uzoq davom etadigan sinxron kod butun sahifani muzlatadi: tugmalar
> bosilmaydi, animatsiya to'xtaydi.

Unda `setTimeout` va `fetch` qanday "bir vaqtda" ishlaydi? Ularni JavaScript
emas, **brauzer** bajaradi va tayyor bo'lganda callback'ni navbatga qo'yadi.

## Call stack

```js
function third() {
  console.log("Zanjir:", new Error().stack.split("\n").length - 1, "level");
  return 3;
}

function second() {
  return third();
}

function first() {
  return second();
}

console.log(first());
```

**Call stack** — bajarilayotgan funksiyalar to'plami. Har chaqiruv ustiga
qo'shiladi, tugagach olinadi. Stack **bo'shaguncha** navbatdagi ish
boshlanmaydi — bu asosiy qoida.

## Ikki navbat

```js
console.log("1 — sinxron");

setTimeout(() => console.log("4 — makrotask (setTimeout)"), 0);

Promise.resolve().then(() => console.log("3 — mikrotask (Promise)"));

console.log("2 — sinxron");
```

Tartib: sinxron kod → mikrotask → makrotask. `setTimeout` `0` ms bilan
yozilsa ham oxirida chiqdi.

> **Atama**
>
> **Makrotask** — `setTimeout`, `setInterval`, hodisa tinglovchilari.
> **Mikrotask** — `Promise` callback'lari (`then`, `catch`, `await` davomi) va
> `queueMicrotask`.
>
> Event loop har makrotaskdan keyin **barcha** mikrotasklarni bajaradi.
> Shuning uchun mikrotasklar har doim oldinroq.

## Tartibni to'liq ko'rish

```js
console.log("1 — startTime");

setTimeout(() => console.log("6 — timeout 1"), 0);
setTimeout(() => console.log("7 — timeout 2"), 0);

Promise.resolve()
  .then(() => console.log("3 — promise 1"))
  .then(() => console.log("5 — promise 2 (ikkinchi bosqich)"));

queueMicrotask(() => console.log("4 — queueMicrotask"));

console.log("2 — end");
```

Qoida: **butun** sinxron kod → **barcha** mikrotasklar → **bitta** makrotask →
yana barcha mikrotasklar → keyingi makrotask.

Zanjirdagi ikkinchi `then` ga e'tibor bering: u `queueMicrotask` dan
**keyin** chiqdi. Sababi — zanjirning har bo'g'ini o'zidan oldingisi
tugagachgina navbatga qo'yiladi, `queueMicrotask` esa allaqachon navbatda
turgan edi.

## await ham mikrotask

```js
async function run() {
  console.log("2 — async startTime");
  await null;
  console.log("4 — await keyini");
}

console.log("1 — boshlandi");
run();
setTimeout(() => console.log("5 — timeout"), 0);
console.log("3 — tugadi");
```

`async` funksiya `await` gacha **sinxron** bajariladi. `await` dan keyingi
qism esa mikrotask navbatiga tushadi — [async/await](https://learncode.uz/javascript/async-await)
Promise ustiga qurilgani shundan.

## Mikrotask makrotaskni kutdirmaydi

```js
setTimeout(() => console.log("Makrotask — oxirida"), 0);

Promise.resolve().then(() => {
  console.log("Mikrotask 1");
  return Promise.resolve();
}).then(() => {
  console.log("Mikrotask 2");
}).then(() => {
  console.log("Mikrotask 3");
});

console.log("Sinxron");
```

Uchta mikrotask ketma-ket bajarildi — makrotask ularning **hammasini** kutdi.

<Callout type="warning" title="Cheksiz mikrotask sahifani muzlatadi">
Mikrotask o'zini qayta navbatga qo'ysa, event loop makrotaskka **hech qachon**
o'tolmaydi:

```js
function infinite() {
  Promise.resolve().then(infinite);   // ❌ sahifa muzlaydi
}
```

`setTimeout` bilan yozilsa esa brauzer nafas oladi.
</Callout>

## Amaliy oqibat — og'ir hisobni bo'lish

```js
function heavy(n) {
  let s = 0;
  for (let i = 0; i < n; i++) s += i;
  return s;
}

const startTime = Date.now();
console.log("Natija:", heavy(20000000));
console.log("Bloklandi:", Date.now() - startTime, "ms");
console.log("Shu elapsed davomida sahifa response bermadi");
```

Bunday hisobni bo'laklarga ajratib, orasida brauzerga navbat berish kerak:

```js
function inChunks(total, bolak, tugadi) {
  let i = 0;
  let s = 0;

  function step() {
    const end = Math.min(i + bolak, total);
    for (; i < end; i++) s += i;

    if (i < total) {
      setTimeout(step, 0);
    } else {
      tugadi(s);
    }
  }

  step();
}

console.log("Boshlandi");

inChunks(5000000, 500000, (result) => {
  console.log("Natija:", result);
});

console.log("Bu darhol chiqdi — sahifa bloklanmadi");
```

Har bo'lak orasida `setTimeout` brauzerga hodisalarni qayta ishlash imkonini
beradi. Haqiqiy loyihalarda og'ir hisob uchun **Web Worker** ishlatiladi — u
alohida oqimda ishlaydi.

## Xulosa jadvali

| Navbat | Nimalar | Qachon |
|---|---|---|
| Sinxron kod | Oddiy qatorlar | Darhol, stack'da |
| Mikrotask | `then`, `catch`, `await`, `queueMicrotask` | Stack bo'shashi bilan, **hammasi** |
| Makrotask | `setTimeout`, `setInterval`, hodisalar | Mikrotasklardan keyin, **bittasi** |

## Amaliy mashq

1. `console.log`, `setTimeout(0)` va `Promise.then` ni aralashtirib yozing —
   tartibni oldindan ayting, keyin tekshiring;
2. `async` funksiyada `await` dan oldin va keyin log qo'ying;
3. uchta zanjirli `then` va bitta `setTimeout` yozib, tartibni kuzating;
4. `while` bilan 500 ms bloklovchi kod yozing;
5. og'ir hisobni `setTimeout` bilan bo'laklarga ajrating;
6. `queueMicrotask` va `setTimeout` ni solishtiring.

1-qadam — bu darsning asosiy sinovi.

## Qisqacha xulosa

- JavaScript **bir oqimli**: bir vaqtda bitta ish bajaradi.
- **Call stack** bo'shamaguncha navbatdagi ish boshlanmaydi.
- **Mikrotask** (Promise, await) makrotaskdan **oldin** bajariladi.
- Har makrotaskdan keyin **barcha** mikrotasklar ishlaydi.
- `setTimeout(..., 0)` "darhol" emas — "navbat kelganda" degani.
- Og'ir sinxron kod sahifani muzlatadi — bo'laklang yoki Worker ishlating.

Keyingi darsda [generator va iterator](https://learncode.uz/javascript/generator-iterator) —
qiymatlarni talab bo'yicha berish.
