WisarWisar
Dasturlash kitobi/5-QISM — Nodejs20 daqiqa

5.1-bob: Node.js kirish — runtime, event loop (chuqur), V8

5-QISM — Node.js Backend · 1-mavzu


1. Kirish va motivatsiya

Mana, kitobning eng katta amaliy qismlaridan biriga — backend (server) dasturlashga keldik. 0.7-bobda Node.js'ni o'rnatdik, 2-QISMda JavaScript'ni chuqur o'rgandik, 0.4-bobda HTTP va server tushunchasini ko'rdik. Endi hammasi birlashadi: JavaScript bilan server yozamiz.

Node.js — JavaScript'ni brauzerdan tashqarida, serverda ishlatadigan muhit (runtime). U tufayli siz bitta til — JavaScript — bilan butun stackni (frontend + backend) yozasiz. Bu — bu kitobning butun mantig'i va Node.js'ning butun dunyoni zabt etgan sababi.

Lekin 5.1-bob shunchaki "Node nima" emas. Bu — Node.js'ning yuraginievent loop va non-blocking I/O mexanizmini — chuqur ochadigan bob. Mana shu mexanizm Node.js'ni qanday qilib bitta thread bilan minglab foydalanuvchiga xizmat ko'rsatishini tushuntiradi. Buni tushunmasdan, Node'da "sehr" bo'lib qoladi; tushunsangiz — siz performance, scalability va "nega serverim qotib qoldi?" muammolarini hal qila olasiz.

O'xshatish (event loop): bitta ofitsiantli restoran. Oddiy ofitsiant bir stolda turib, ovqat pishishini kutadi (blocking) — boshqa stollar och qoladi. Aqlli ofitsiant (Node) esa buyurtmani oshxonaga beradi va kutmasdan boshqa stollarga xizmat qiladi; ovqat tayyor bo'lganda (event), uni olib keladi (callback). Bitta ofitsiant — yuzlab stol! Bu — non-blocking I/O.

Nega bu bob nihoyatda muhim?

  • Butun 5-QISM (23 bob) va NestJS (8-QISM) shu poydevorga quriladi.
  • Performance/scalability — "nega Node tez?", "nega serverim sekin?" — javobi shu yerda.
  • Intervyu — event loop, process.nextTick vs setImmediate — backend intervyularning klassikasi.
  • 0.1 (CPU/thread), 0.2 (process/OS), 0.5 (V8/event loop kirishi), 2.11 (async) — hammasi bu yerda birlashadi va chuqurlashadi.

2. Nazariya — chuqur tushuntirish

2.1. Node.js aslida nima? (3 ta noto'g'ri tushuncha)

Avvalo, Node.js nima emasligini aniqlaylik (eng ko'p chalkashlik):

  • Node.js — dasturlash tili emas (til — JavaScript).
  • Node.js — framework emas (Express — framework, Node emas).
  • Node.js — runtime (ishga tushirish muhiti): JavaScript kodni brauzerdan tashqarida ishlatadigan dastur.

Ya'ni: JavaScript — til; V8 — uni mashina kodiga aylantiradigan engine 0.5-bob; Node.js — V8'ni o'rab, unga server qobiliyatlari (fayl, tarmoq, OS) qo'shgan muhit.

O'xshatish: JavaScript — suv. Brauzer — bir idish (shisha). Node.js — boshqa idish (chelak). Suv (til) bir xil, lekin idish (muhit) har xil imkoniyat beradi: brauzerda DOM, Node'da fayl/server.

2.2. Node.js arxitekturasi — uch asosiy qism

Node.js — bir necha komponentdan tashkil topgan tizim (nodejs.org/libuv hujjatlariga ko'ra):

text
   ┌──────────────────────────────────────────────────┐
   │           SIZNING JS KODINGIZ (app.js)             │
   ├──────────────────────────────────────────────────┤
   │   Node.js API (fs, http, crypto, path... — 5.3)    │
   ├───────────────────────────┬──────────────────────┤
   │      V8 Engine             │       libuv (C)       │
   │  (JS  mashina kodi — 0.5) │  (event loop, I/O,    │
   │                            │   thread pool)        │
   ├───────────────────────────┴──────────────────────┤
   │      Operatsion tizim (OS — 0.2): fayl, tarmoq      │
   └──────────────────────────────────────────────────┘
  • V8 — JavaScript'ni bajaradi (mashina kodiga aylantiradi — 0.5). U faqat JS ni biladi; I/O, tarmoq haqida hech narsa bilmaydi.
  • libuv — C tilida yozilgan kutubxona; event loop va asinxron I/O (fayl, tarmoq) shu yerda yashaydi. Node'ning "sehri" — aynan shu.
  • Node API — V8 va libuv'ni JavaScript'ga bog'laydigan ko'prik (fs, http, crypto — 5.3).

Muhim: event loop V8'da emas, libuv'da. V8 — sinxron (faqat JS bajaradi); butun asinxronlik (event loop, I/O orkestrlash) — libuv'ning ishi (libuv docs).

2.3. V8 — JavaScript'ni bajaruvchi (0.5 chuqurroq)

V8 (0.5-bobda ko'rgandik) — Google'ning JS engine'i: JavaScript'ni mashina kodiga kompilyatsiya qiladi (Parser AST Ignition bytecode TurboFan JIT — 0.5). Node.js xuddi shu V8'ni ishlatadi (brauzer Chrome bilan bir xil).

V8'ning muhim xususiyati — u fundamental sinxron va bitta thread'da ishlaydi (0.1, 0.5). U I/O, tarmoq, thread haqida hech narsa bilmaydi. Demak, agar Node faqat V8'dan iborat bo'lsa — har fayl o'qishda butun dastur qotib qolardi. Aynan shu yerda libuv kerak bo'ladi.

2.4. libuv — I/O orkestratori va event loop uyi

libuv — C tilida yozilgan, platformalararo kutubxona (dastlab Node uchun yaratilgan — libuv docs). U Node'da butun asinxron ishni boshqaradi: fayl tizimi 0.2-bob, tarmoq 0.4-bob, DNS, child process, va eng muhimi — event loop.

libuv ikki mexanizmdan foydalanadi:

  1. OS'ning native asinxron API'lari (tarmoq uchun): Linux — epoll, macOS — kqueue, Windows — IOCP. Bular OS yadrosi darajasida 0.2-bob ishlaydi — juda samarali.
  2. Thread pool (fayl/CPU uchun): native async API yo'q amallar uchun 2.10-bob.

2.5. Single-threaded JS + non-blocking I/O — Node'ning yuragi

Mana eng muhim g'oya. Node.js'da sizning JS kodingiz bitta thread'da ishlaydi (0.1, 0.2: single-threaded). "Bitta thread bilan qanday minglab foydalanuvchiga xizmat qiladi?" — javob non-blocking I/Oda.

text
  ANANAVIY SERVER (PHP, har so'rovga thread):
  1000 foydalanuvchi  1000 OS thread  ko'p RAM, kontekst almashinuvi 0.2-bob

  NODE.JS (bitta thread + event loop):
  1000 foydalanuvchi  bitta thread, har so'rov "event" sifatida ro'yxatga olinadi
   I/O OS'ga/thread pool'ga topshiriladi  kutmaydi  keyingisini xizmat qiladi
   I/O tayyor bo'lganda callback ishlaydi

Nega bu inqilobiy: har HTTP so'rovga yangi OS thread ochilmaydi (qimmat — 0.2). So'rov event sifatida ro'yxatga olinadi; I/O (DB, fayl, tarmoq) kutilmaydi — boshqa so'rovlar xizmat qilinadi; natija tayyor bo'lganda callback chaqiriladi. Shuning uchun Node 10,000+ bir vaqtdagi ulanishni 10,000 thread'siz uddalaydi. Bu — I/O-og'ir (ko'p so'rov) ilovalar uchun ideal.

2.6. Blocking vs non-blocking (sync vs async)

Node API'larining ko'pi ikki versiyada: blocking (sinxron) va non-blocking (asinxron — 2.11):

text
  BLOCKING (sync):  natija kelguncha THREAD TO'XTAYDI (butun server kutadi!)
     const data = fs.readFileSync("katta.txt");   //  server qotadi

  NON-BLOCKING (async):  topshiriladi, thread DAVOM ETADI, callback keyin
     fs.readFile("katta.txt", (err, data) => {...});   //  server javob beradi

Oltin qoida: server kodida hech qachon blocking (...Sync) API ishlatmang (skriptlarda mayli). Bitta readFileSync butun serverni — barcha foydalanuvchilarni — to'xtatadi 2.5-bob. Doim async (callback / Promise / async-await — 2.11).

2.7. Event loop — to'liq mexanizm (6 faza)

Event loop — libuv'ning yuragi: asinxron callback'larni qachon va qaysi tartibda ishga tushirishni boshqaradigan cheksiz tsikl. U fazalardan iborat; har fazada o'ziga tegishli callback'lar navbati (FIFO — 3.4) bajariladi (nodejs.org/libuv):

text
   ┌───────────────────────────┐
┌─▶│   1. timers                │  setTimeout, setInterval callback'lari
│  ├───────────────────────────┤
│  │   2. pending callbacks     │  ba'zi tizim I/O callback'lari (kechiktirilgan)
│  ├───────────────────────────┤
│  │   3. idle, prepare         │  ichki (Node o'zi ishlatadi)
│  ├───────────────────────────┤
│  │   4. poll                  │  ◀── ASOSIY: I/O callback'lar (fayl, tarmoq);
│  │                            │      yangi I/O eventlarni kutadi/oladi
│  ├───────────────────────────┤
│  │   5. check                 │  setImmediate callback'lari
│  ├───────────────────────────┤
│  │   6. close callbacks       │  'close' eventlari (socket.on('close'))
│  └───────────────────────────┘
└────── (har fazadan keyin: microtask navbatlari — 2.8)
Faza Nima bajaradi
timers setTimeout/setInterval — vaqti kelgan callback'lar
pending callbacks kechiktirilgan tizim I/O callback'lari
idle, prepare ichki (Node o'zi)
poll eng muhim — I/O callback'lar; yangi I/O kutadi/oladi
check setImmediate callback'lari
close callbacks close eventlari (resurs yopilishi)

poll fazasi — yurak: event loop vaqtining ko'rini shu yerda o'tkazadi. I/O callback'larni bajaradi; agar ish yo'q bo'lsa, yangi I/O eventlarni kutadi (yoki timer/immediate bo'lsa, o'tadi). Tarmoq/fayl natijalari shu yerda "qaytadi".

2.8. Microtask navbatlari — fazalar orasida

Event loop fazalari libuv'da. Lekin yana ikki microtask navbati bor — ular libuv'da emas, Node runtime'da, va ular har faza orasida, fazalardan oldin bajariladi (nodejs.org):

  1. process.nextTick() navbati — eng yuqori ustuvorlik.
  2. Promise (microtask) navbati.then/catch/finally, await 2.11-bob.
text
   Har callback'dan keyin (yoki faza tugashi bilan):
   1. nextTick navbati TO'LIQ bo'shatiladi (eng oldin)
   2. Promise navbati TO'LIQ bo'shatiladi
   3. keyin event loop keyingi fazaga o'tadi

Ustuvorlik tartibi (yodlang): sinxron kod process.nextTick Promise (microtask) timers/I/O/check (macrotask fazalar). Bu — event loop tartibini bashorat qilishning kaliti (Misol 3).

2.9. process.nextTick vs setImmediate vs setTimeout

Uchta "keyinroq bajar" mexanizmi, lekin har xil vaqtda:

Mexanizm Qachon ishlaydi
process.nextTick(cb) darrov, joriy amaldan keyin, har fazadan oldin (eng tez)
Promise.then(cb) nextTick'dan keyin (microtask)
setImmediate(cb) check fazasida (poll'dan keyin)
setTimeout(cb, 0) timers fazasida (keyingi tsiklda)
js
console.log("1: sinxron");
setTimeout(() => console.log("5: setTimeout"), 0);   // timers fazasi
setImmediate(() => console.log("4: setImmediate"));   // check fazasi
Promise.resolve().then(() => console.log("3: Promise"));  // microtask
process.nextTick(() => console.log("2: nextTick"));   // eng oldin
console.log("1.5: sinxron");
// Tartib: 1  1.5  2  3  (4 yoki 5, kontekstga bog'liq)

process.nextTick "ochlik" (starvation) xavfi: u har fazadan oldin to'liq bo'shatiladi. Agar nextTick ichida yana nextTick qo'shaversa — event loop hech qachon keyingi fazaga o'tmaydi (I/O bloklanadi). Ehtiyot bo'ling (Misol 5).

2.10. Thread pool — libuv'ning yashirin ishchilari

Node "single-threaded" deyilsa-da, libuv'ning thread pool'i bor (default 4 ta thread — libuv docs). JS kodi bitta thread'da, lekin ba'zi og'ir/blocking amallar bu pool'da, parallel (0.1: yadrolar) bajariladi:

Thread pool'ga tushadigan amallar:

  • Fayl tizimi (fs — 5.3) — native async API yo'q, shuning uchun pool.
  • DNS (dns.lookup).
  • Crypto (crypto.pbkdf2, bcrypt — 5.15) — CPU-og'ir.
  • Zlib (siqish) — CPU-og'ir.
bash
# Thread pool hajmini o'zgartirish (default 4)
UV_THREADPOOL_SIZE=8 node app.js

Muhim farq 2.11-bob: tarmoq I/O (HTTP, TCP) thread pool'ni ishlatmaydi — u OS'ning native async API'si (epoll/kqueue/IOCP) bilan, asosiy thread'da. Fayl/CPU amallari esa thread pool'da. Shuning uchun Node minglab tarmoq ulanishini 4 thread bilan ham uddalaydi (tarmoq pool'siz).

2.11. Network I/O vs File I/O (nega farq qiladi)

text
  TARMOQ I/O (HTTP, TCP, socket):
     OS native async (epoll/kqueue/IOCP) — 0.2
     thread pool KERAK EMAS
     minglab ulanish, asosiy thread'da samarali

  FAYL I/O (fs), DNS, crypto, zlib:
     native async API yo'q
     libuv THREAD POOL (default 4) — parallel
     5 ta og'ir crypto bir vaqtda  4 tasi parallel, 5-chisi kutadi

Bu farq performance'da muhim: agar ilovang ko'p fayl/crypto ishlatsa, thread pool (4) bottleneck bo'lishi mumkin — UV_THREADPOOL_SIZE ni oshirish kerak 2.10-bob.

2.12. Node global obyektlar va process

Brauzerda window global obyekt edi 0.5-bob; Node'da global (va globalThis). Node'ning eng muhim global obyekti — process (joriy Node process haqida — 0.2):

js
process.argv          // buyruq qatori argumentlari (0.3, 0.4) — ["node", "app.js", ...]
process.env           // environment variables 5.8-bob — process.env.PORT
process.cwd()         // joriy ish papkasi (0.2)
process.platform      // "linux" / "win32" / "darwin" (0.2)
process.pid           // process ID (0.2)
process.exit(0)       // process'ni to'xtatish (0 — muvaffaqiyat)
process.on("exit", cb)// process tugashida (event — 5.4)
__dirname             // joriy fayl papkasi (0.2, 0.7)
__filename            // joriy fayl to'liq yo'li

2.13. REPL va Node'ni ishga tushirish

bash
node app.js           # faylni ishga tushirish (0.7)
node                  # REPL (interaktiv — har qatorni darrov bajaradi)
node --watch app.js   # fayl o'zgarsa qayta ishga tushiradi (nodemon'siz)
node -e "console.log(2+2)"   # bir qatorli kod

REPL (Read-Eval-Print Loop — 0.3: shell ham REPL) — node deb yozsangiz ochiladi; JS'ni darrov sinab ko'rish uchun (.exit bilan chiqasiz).

2.14. Node vs Brauzer JavaScript (farqlar)

Brauzer Node.js
Global obyekt window global / globalThis
DOM (2.16) bor yo'q (server'da sahifa yo'q)
Fayl tizimi (fs) yo'q (xavfsizlik) bor (5.3)
Modul ESM (0.5) ESM + CommonJS (2.15)
process yo'q bor
Event loop brauzer beradi libuv beradi

Til (JavaScript) bir xil; muhit (API) har xil.

2.15. CommonJS vs ESM — Node'da ikki modul tizimi

Node'da kodni bo'laklarga (modullarga) ajratishning ikki usuli bor (5.2 da chuqurroq):

  • CommonJS (CJS) — Node'ning tarixiy/an'anaviy tizimi. require() bilan import, module.exports bilan export. Sinxron yuklanadi; standart kengaytma .js.
  • ESM (ECMAScript Modules) — JavaScript'ning rasmiy standart tizimi (brauzer ham shuni ishlatadi — 0.5). import/export bilan; standart kengaytma .mjs (yoki package.json da "type": "module" — 5.2).
js
// CommonJS (an'anaviy)
const fs = require("fs");           // import
module.exports = { salom };          // export

// ESM (standart)
import fs from "fs";                  // import
export const salom = () => {};        // export

Qaysi birini tanlash? Yangi loyihalarda ESM afzal (standart, brauzer bilan bir xil). Lekin ko'p eski paket va misol hali CommonJSda — shuning uchun ikkalasini ham bilish kerak. Bu bobning kod misollarida require (CommonJS) ishlatiladi, chunki u Node'da konfiguratsiyasiz ishlaydi. Modullarni 5.2-bobda batafsil ochamiz.


3. Sintaksis va ishga tushirish

bash
# Ishga tushirish
node app.js              node --watch app.js

# Async API (server'da DOIM shu — 2.6)
fs.readFile(path, cb)    # non-blocking 
fs.readFileSync(path)    # blocking  (server'da emas)

# Timing (2.9)
process.nextTick(cb)     # eng oldin (microtask'dan ham)
queueMicrotask(cb)       # Promise microtask
setImmediate(cb)         # check fazasi
setTimeout(cb, ms)       # timers fazasi

# Global
process.argv / .env / .exit()    __dirname / __filename

4. Batafsil kod namunalari

Misol 1 — Birinchi Node dastur va process (2.12)

js
// app.js — Node muhitini tekshiramiz
console.log("Salom, Node!");

console.log("Versiya:", process.version);        // masalan v22.x
console.log("Platforma:", process.platform);     // "win32" / "linux" (0.2)
console.log("Joriy papka:", process.cwd());      // (0.2)
console.log("Bu fayl:", __filename);             // to'liq yo'l (0.7)
console.log("Argumentlar:", process.argv);       // ["node", "app.js", ...]

// Buyruq qatori argumentini olish (0.3, 0.4: misol 4)
const ism = process.argv[2] ?? "Mehmon";         // node app.js Ali  "Ali" (2.1)
console.log(`Salom, ${ism}!`);
// Ishga tushirish: node app.js Ali

Misol 2 — Blocking vs Non-blocking 2.6-bob — server'ning hayot-mamot masalasi

js
const fs = require("fs");   // core modul (5.3, 2.14: CommonJS)

//  BLOCKING — butun thread to'xtaydi (server qotadi!)
console.log("1: boshlandi");
const data = fs.readFileSync("fayl.txt", "utf8");   // KUTADI (2.6)
console.log("2: fayl o'qildi:", data.length, "belgi");
console.log("3: tugadi");
// Tartib: 1  2  3 (lekin 1 va 2 orasida server HECH KIMGA javob bermaydi)

//  NON-BLOCKING — thread davom etadi, callback keyin
console.log("A: boshlandi");
fs.readFile("fayl.txt", "utf8", (err, data) => {    // topshiriladi (2.6)
  if (err) return console.error("Xato:", err.message);   // (2.12: error handling)
  console.log("C: fayl o'qildi:", data.length);     // KEYIN (poll fazasi — 2.7)
});
console.log("B: tugadi");
// Tartib: A  B  C (fayl o'qilayotganda server boshqa ishni bajaradi)

Misol 3 — Event loop tartibi (2.7, 2.8, 2.9) — intervyu klassikasi

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

setTimeout(() => console.log("6 — setTimeout (timers)"), 0);   // timers (2.7)
setImmediate(() => console.log("5 — setImmediate (check)"));    // check (2.7)

Promise.resolve().then(() => console.log("4 — Promise (microtask)"));  // (2.8)
process.nextTick(() => console.log("3 — nextTick (eng oldin)"));        // (2.8)

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

// NATIJA:
// 1 — sinxron (birinchi)        sinxron kod birinchi
// 2 — sinxron (ikkinchi)        barcha sinxron tugaydi
// 3 — nextTick                  nextTick navbati (2.8: eng yuqori)
// 4 — Promise                   microtask navbati
// 5 — setImmediate (yoki 6)     macrotask fazalar
// 6 — setTimeout
// Saboq: sinxron  nextTick  Promise  timer/check (2.8)

Misol 4 — setTimeout vs setImmediate (2.9)

js
// I/O callback ICHIDA: setImmediate DOIM setTimeout'dan oldin (poll  check)
const fs = require("fs");

fs.readFile(__filename, () => {              // poll fazasi (2.7)
  setTimeout(() => console.log("setTimeout"), 0);   // timers (keyingi tsikl)
  setImmediate(() => console.log("setImmediate")); // check (DARROV poll'dan keyin)
});
// I/O ichida DOIM: "setImmediate"  "setTimeout"
// (poll tugagach check keladi; timers keyingi aylanishda — 2.7)

Misol 5 — process.nextTick "starvation" xavfi (2.9)

js
//  XAVFLI — nextTick ichida nextTick  event loop QOTADI
let son = 0;
function cheksizTick() {
  if (son < 5) {       // (chegara qo'ydik — aks holda mangu)
    console.log("nextTick", ++son);
    process.nextTick(cheksizTick);   // har fazadan oldin yana qo'shadi (2.8)
  }
}
process.nextTick(cheksizTick);
setTimeout(() => console.log("Men ham bormi?"), 0);
// nextTick'lar TUGAGUNCHA setTimeout (timer) ishlamaydi (2.8)
// Agar chegara bo'lmasa — setTimeout HECH QACHON ishlamaydi (starvation!)

Misol 6 — Thread pool (parallel crypto — 2.10, 2.11)

js
const crypto = require("crypto");   // (5.3)

// pbkdf2 — CPU-og'ir (thread pool'da, default 4 — 2.10)
const boshlanish = Date.now();
for (let i = 1; i <= 4; i++) {
  crypto.pbkdf2("parol", "tuz", 100000, 64, "sha512", () => {
    console.log(`${i}: ${Date.now() - boshlanish}ms`);   // ~bir vaqtda (parallel!)
  });
}
// 4 ta bir vaqtda tugaydi (4 thread — 2.10). 5-chi bo'lsa — kutardi.
// UV_THREADPOOL_SIZE=8 node app.js bilan 8 thread (2.10)

Misol 7 — Event loop'ni bloklash (og'ir hisob) va yechim

js
//  XATO — og'ir sinxron hisob event loop'ni bloklaydi (0.5: sahifa qotishi)
const http = require("http");
http.createServer((req, res) => {
  // Har so'rovda OG'IR hisob — BUTUN server qotadi (boshqalar kutadi!)
  let yigindi = 0;
  for (let i = 0; i < 1e9; i++) yigindi += i;   // CPU-og'ir, bloklaydi (2.5)
  res.end(`Natija: ${yigindi}`);
}).listen(3000);

//  YECHIM — og'ir CPU ishni Worker Thread'ga chiqarish (alohida thread)
// const { Worker } = require("worker_threads");  (5.4 ga bog'liq)
// Yoki ishni bo'laklab, setImmediate bilan navbatga qo'yish
// Saboq: Node tarmoq I/O uchun ajoyib, lekin CPU-og'ir ish uchun ehtiyot (2.11)

Misol 8 — process obyekti (argv, env, events — 2.12)

js
// Environment variable 5.8-bob — DEFAULT bilan
const PORT = process.env.PORT || 3000;
console.log("Port:", PORT);   // PORT=8080 node app.js  8080

// Process eventlari (5.4: EventEmitter)
process.on("exit", (kod) => {
  console.log(`Process tugadi, kod: ${kod}`);   // tozalash uchun (0.2)
});
process.on("uncaughtException", (xato) => {     // ushlanmagan xato (2.12)
  console.error("Halokatli xato:", xato.message);
  process.exit(1);   // 1 — xato bilan tugash (0.3: exit kod)
});

console.log("Dastur ishlayapti...");
// process.exit(0);   // ataylab to'xtatish (0 — muvaffaqiyat)

Misol 9 — Oddiy HTTP server (scalability namoyishi — 2.5)

js
const http = require("http");   // (5.5 da chuqur)

// Bitta thread, lekin minglab so'rovni uddalaydi (non-blocking — 2.5)
const server = http.createServer((req, res) => {
  // Har so'rov — "event"; yangi thread OCHILMAYDI (2.5)
  console.log(`So'rov: ${req.method} ${req.url}`);   // (0.4: metod, url)
  res.writeHead(200, { "Content-Type": "application/json" });   // (0.4: status)
  res.end(JSON.stringify({ xabar: "Salom, backend!", vaqt: Date.now() }));
});

server.listen(3000, () => {
  console.log("Server http://localhost:3000 da ishlayapti");
});
// node app.js  brauzerda localhost:3000
// Bu server bitta thread bilan minglab ulanishni uddalaydi (event loop — 2.7)

5. To'g'ri va noto'g'ri holatlar

1) Server'da blocking (Sync) API

js
//  butun serverni to'xtatadi 2.6-bob — barcha foydalanuvchi kutadi
const data = fs.readFileSync("katta.txt");

//  non-blocking (async — 2.11)
const data = await fs.promises.readFile("katta.txt");

2) Event loop'ni og'ir CPU bilan bloklash

js
//  og'ir tsikl/hisob handler ichida  server qotadi (Misol 7)
for (let i = 0; i < 1e9; i++) {...}

//  Worker Thread, bo'laklash, yoki tashqi xizmat (2.11)

3) process.nextTick ni rekursiv ishlatish

js
//  starvation — event loop qotadi (2.9, Misol 5)
function f() { process.nextTick(f); }

//  rekursiv kechiktirish kerak bo'lsa — setImmediate (check fazasi)
function f() { setImmediate(f); }

4) Xatoni async'da ushlamaslik

js
//  callback'da err tekshirilmadi (2.12)
fs.readFile("yoq.txt", (err, data) => { console.log(data.length); });
// err bo'lsa, data undefined  xato

//  doim err tekshir (Node callback konvensiyasi: err birinchi)
fs.readFile("yoq.txt", (err, data) => {
  if (err) return console.error(err.message);
  console.log(data.length);
});

5) Brauzer API'sini Node'da kutish

js
//  Node'da DOM/window yo'q (2.14)
document.querySelector(...);   // ReferenceError
localStorage.setItem(...);     // yo'q

//  Node API: fs, process, global (2.12, 2.14)

6. Keng tarqalgan xatolar va yechimlari

Xato 1 — ReferenceError: document is not defined (yoki window/localStorage)

Sababi: brauzer API'si Node'da yo'q 2.14-bob. Yechimi: server kodda DOM ishlatmang; Node API (fs, http) ishlating.

Xato 2 — Server sekin/qotib qoladi

Sababi: blocking API yoki og'ir CPU event loop'ni bloklaydi (2.5, 2.6). Yechimi: async API; og'ir ishni Worker Thread'ga (2.11, Misol 7).

Xato 3 — Error: EADDRINUSE: address already in use :::3000

Sababi: 3000-port band (0.2, 0.4). Yechimi: boshqa port; yoki band process'ni topib to'xtat (0.3: lsof/netstat).

Xato 4 — Cannot find module 'x'

Sababi: modul o'rnatilmagan yoki yo'l xato (2.14, 0.7). Yechimi: npm install x; core modul nomini tekshiring (fs, http).

Xato 5 — Async natija undefined

Sababi: async amal tugashini kutmasdan natijaga murojaat 2.11-bob. Yechimi: callback/Promise/await ichida ishlating; event loop tartibini eslang 2.8-bob.

Xato 6 — UnhandledPromiseRejection (Node process qulashi)

Sababi: ushlanmagan Promise rad etilishi 2.11-bob. Yechimi: try/catch/.catch 2.12-bob; process.on("unhandledRejection").


7. Integratsiya — bu mavzu stack'ning qayerida uchraydi

  • JavaScript (2-QISM): Node — JS'ni serverda ishlatadi; async 2.11-bob — event loop ustida.
  • 0.1, 0.2, 0.5: thread 0.1-bob, process 0.2-bob, V8/event loop kirishi 0.5-bob — bu yerda chuqurlashadi.
  • npm/modullar (5.2, 2.14): Node ekotizimi.
  • Core modullar 5.3-bob: fs/http/crypto — libuv ustida.
  • Streams/Events 5.4-bob: event loop bilan ishlaydi.
  • HTTP/Express (5.5, 5.6): server — event loop'da ishlaydi.
  • NestJS (8): Node ustiga qurilgan.
  • Performance 15.5-bob: event loop bloklash — debug.

8. Eng yaxshi amaliyotlar (best practices)

  • Server'da hech qachon blocking (...Sync) API — doim async 2.6-bob.
  • Event loop'ni bloklamang — og'ir CPU ishni Worker Thread'ga; tarmoq I/O Node'ning kuchi 2.11-bob.
  • Async callback'larda err ni doim tekshiring (Node konvensiyasi — error-first — 4-holat).
  • process.nextTick ni ehtiyot bilan — starvation xavfi; ko'pincha setImmediate yoki Promise afzal 2.9-bob.
  • Promise/async-await ishlating (callback hell o'rniga — 2.11).
  • Event loop tartibini tushuning — nextTick Promise timer/immediate 2.8-bob; performance/debug uchun.
  • UV_THREADPOOL_SIZE — ko'p fayl/crypto ishlatadigan ilovada oshiring 2.10-bob.
  • process.env bilan konfiguratsiya 5.8-bob; __dirname bilan yo'l 0.2-bob.
  • Ushlanmagan xato/rejection'ni boshqar (process.on — 6-holat).

9. Amaliy loyiha: "Event Loop Laboratoriyasi va Birinchi Server"

Node'ning yuragini — event loop va non-blocking I/O'ni — amalda his qilish.

Maqsad

Event loop fazalarini, microtask ustuvorligini, blocking vs non-blocking farqini va thread pool'ni amalda tajriba qilib, mustahkam tushuncha hosil qilish.

Talablar (requirements)

  1. Event loop tartibi: console.log, setTimeout, setImmediate, Promise.then, process.nextTick ni aralashtirib, natija tartibini avval bashorat qiling, keyin ishlatib tekshiring (Misol 3, 2.8).
  2. Blocking vs non-blocking: bir faylni readFileSync va readFile bilan o'qib, ularning oqim tartibini va "qotish" farqini ko'rsating (Misol 2, 2.6).
  3. setTimeout vs setImmediate: I/O callback ichida va tashqarisida farqini ko'rsating (Misol 4, 2.9).
  4. Thread pool: 4 va 8 ta crypto.pbkdf2 ni parallel ishlatib, vaqtlarni o'lchang; UV_THREADPOOL_SIZE o'zgartirib farqni ko'ring (Misol 6, 2.10).
  5. Event loop bloklash: og'ir CPU tsikl bilan serverni bloklab, keyin yechim (bo'laklash yoki Worker) bilan tuzating (Misol 7, 2.11).
  6. process tahlili: argv, env, platform, cwd ni chiqaruvchi CLI; argument va env bilan ishlash (Misol 8, 2.12).
  7. Birinchi HTTP server: so'rovlarni loglovchi, JSON qaytaruvchi server (Misol 9); brauzer/curl bilan sinang 0.4-bob.
  8. Har tajriba uchun nima sodir bo'lishini va NEGA ekanini izohda yozing (event loop fazasi bilan).

Maslahatlar (hint)

  • Tartibni avval qog'ozga bashorat qiling 2.8-bob, keyin ishlatib solishtiring — bu eng yaxshi o'rganish.
  • console.time/timeEnd 0.5-bob bilan thread pool/blocking vaqtini o'lchang.
  • UV_THREADPOOL_SIZE=8 node app.js (Git Bash'da — 0.3).
  • HTTP server: http.createServer + res.end (Misol 9, 5.5 da chuqur).
  • Blocking demoda — server ishlayotganda boshqa so'rov yuborib, "qotish"ni his qiling.
  • process.argv[2] — birinchi haqiqiy argument 0.3-bob.

"Tayyor" mezonlari (acceptance criteria)

  • Event loop tartibi bashorat qilingan va tekshirilgan (nextTick Promise timer/immediate).
  • Blocking vs non-blocking farqi ko'rsatilgan va izohlangan.
  • setTimeout vs setImmediate (I/O ichida/tashqarisida) farqi ko'rsatilgan.
  • Thread pool 4 vs 8 vaqti o'lchangan.
  • Event loop bloklash muammosi va yechimi ko'rsatilgan.
  • process CLI argument/env bilan ishlaydi.
  • HTTP server so'rovlarni loglaydi va JSON qaytaradi.
  • Har tajriba "nima va nega" izohi bilan.

Yechim kodi ataylab berilmagan — bu loyihani o'zingiz yozib ko'ring.


10. Xulosa va keyingi bobga ko'prik

Bu bobda Node.js'ning yuragini chuqur ochdik:

  • Node.js — runtime (til/framework emas): V8 (JS bajaradi — 0.5) + libuv (event loop, I/O — C) + Node API (fs/http).
  • Single-threaded JS + non-blocking I/O — bitta thread bilan minglab ulanish (tarmoq native async, fayl/CPU — thread pool).
  • Event loop (libuv) 6 faza: timers pending idle/prepare poll (I/O) check (setImmediate) close.
  • Microtask navbatlari (Node runtime, fazalar orasida): nextTick (eng yuqori) Promise.
  • Ustuvorlik: sinxron nextTick Promise timer/I/O/check.
  • Thread pool (default 4) — fayl/DNS/crypto; tarmoq esa OS native (pool'siz).
  • process — argv/env/exit; server'da hech qachon blocking API.

Keyingi bob — 5.2-bob: npm, package.json, dependencies, scripts, semver. Node'ning ishlashini bildik; endi uning ekotizimini — millionlab paketni boshqaradigan npmni chuqur o'rganamiz (0.7-bobda boshlagandik). package.json, dependency turlari, scripts, semantic versioning — har bir Node/frontend loyihaning poydevori.


Foydalanilgan rasmiy/ishonchli manbalar

  • nodejs.org/learn — The Node.js Event Loop, Timers, and process.nextTick
  • docs.libuv.org — libuv design overview, event loop, thread pool
  • Node.js rasmiy hujjatlari — V8, libuv, process, global obyektlar

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
5.1-bob: Node.js kirish — runtime, event loop (chuqur), V8 — Wisar