JavaScript'da sinxron va asinxron kod farqi, single-threaded tabiati, callback tushunchasi, Callback Hell muammosi, Error-First callback naqshi va asinxron xatoliklarni boshqarish.
Bu bilan PART 4 (Asynchronous JavaScript) boshlanadi — bu qism JavaScript'ni chuqur tushunish uchun eng muhim, ayni paytda eng qiyin qismlardan biri. Callback'lardan boshlaymiz, chunki ular — Promise va async/await'ning asosidir.
🍳 Sinxron — bu bitta oshpaz restoran: u bir taomni to'liq tayyorlab bo'lmaguncha, keyingi buyurtmaga o'tmaydi. Mijozlar navbatda kutishadi.
⏱️ Asinxron — bu bir nechta plita bir vaqtda ishlaydigan oshxona: oshpaz bitta taomni "pishishga qo'yib", uni kutib turmasdan, boshqa taom bilan shug'ullanadi. Birinchi taom tayyor bo'lganda, unga xabar keladi.
script.jsJavaScriptconsole.log("1");console.log("2");console.log("3");// Natija: 1, 2, 3 (qatorma-qator)
script.jsJavaScriptconsole.log("1");setTimeout(function () {console.log("2");}, 1000);console.log("3");// Natija: 1, 3, 2 (2 — 1 soniyadan keyin, lekin 3 undan oldin chiqadi!)
setTimeout — kodni darhol emas, balki 1000 millisekund (1 soniya)dan keyin bajarishga "rejalashtiradi". Shu bilan birga, JavaScript uni kutib turmasdan, keyingi qatorga (console.log("3")) o'tadi.
🔥 Important
Bu — JavaScript'ning single-threaded (bitta oqimli) tabiati bilan bog'liq: u bir vaqtning o'zida faqat bitta amalni bajara oladi, lekin asinxron amallarni "fonga" jo'natib, ularni keyinroq, tayyor bo'lganda qayta ishlaydi. Bu mexanizm Chapter 29'da (Event Loop) chuqur tushuntiriladi.
Callback — boshqa functionga argument sifatida uzatiladigan va o'sha function ichida (odatda ma'lum vaqt yoki hodisadan keyin) chaqiriladigan function.
Agar biror amal darhol tugamasa (masalan, serverdan ma'lumot olish, fayl o'qish, timer), dastur "amal tugaguncha nima qilish kerakligini" oldindan bilishi kerak. Callback — aynan shu "keyin nima qilish kerak" degan ko'rsatmani beradi.
script.jsJavaScriptfunction fetchUserData(callback) {console.log("Ma'lumot olinmoqda...");setTimeout(function () {let userData = { name: "Ali", age: 25 };callback(userData);}, 2000);}fetchUserData(function (data) {console.log("Ma'lumot keldi: " + data.name);});console.log("Boshqa ishlar davom etmoqda...");
Natija:
code.textTEXTMa'lumot olinmoqda...Boshqa ishlar davom etmoqda...(2 soniyadan keyin)Ma'lumot keldi: Ali
🔗 Connection
Bu — Chapter 14'da o'rgangan Higher-Order Function tushunchasining asinxron kontekstdagi qo'llanilishi: fetchUserData — callback function qabul qiluvchi HOF.
Agar bir nechta asinxron amal ketma-ket (biri tugagach ikkinchisi boshlanishi kerak bo'lganda) bajarilishi kerak bo'lsa, callback'lar ichida callback yozish kerak bo'ladi — bu natijada kod "chuqurlashib", o'qish qiyin bo'lib qoladi. Bu holat "Callback Hell" (yoki "Pyramid of Doom") deb ataladi.
script.jsJavaScriptgetUser(1, function (user) {getPosts(user.id, function (posts) {getComments(posts[0].id, function (comments) {getLikes(comments[0].id, function (likes) {console.log(likes);// Bu yerga qadar 4 marta "ichkariga kirib ketdik"});});});});
code.textTEXTgetUser(function() {getPosts(function() {getComments(function() {getLikes(function() {// ← har bir qadamda kod o'ngga "siljib" boradi});});});});
Har bir keyingi amal, oldingisining callback'i ichida yozilishi kerak (chunki u oldingi natijaga bog'liq — masalan, posts olish uchun user.id kerak). Bu esa kodni tobora "chuqurlashtirib", o'qish va xato topishni qiyinlashtiradi.
⚠️ Common Mistake
Callback Hell — faqat "chiroysiz kod" muammosi emas, balki xatolarni boshqarish (error handling)ni ham murakkablashtiradi: har bir darajada alohida xatolikni tekshirish kerak bo'ladi.
Bu muammoni hal qilish uchun Promise (Chapter 27) va async/await (Chapter 28) yaratilgan — ular xuddi shu asinxron mantiqni ancha tekis va o'qish oson formatda yozish imkonini beradi.
🔗 Connection
Callback Hell — nega Promise yaratilganini tushunish uchun eng muhim "muammo" hisoblanadi. Keyingi bobda buni qanday hal qilishni ko'ramiz.
Node.js va ko'plab JavaScript kutubxonalarida, callback'larning birinchi argumenti odatda xatolik uchun ajratiladi — bu naqsh "Error-First Callback" deb ataladi.
script.jsJavaScriptfunction readFile(filename, callback) {setTimeout(function () {if (filename === "") {callback(new Error("Fayl nomi bo'sh"), null);} else {callback(null, "Fayl mazmuni bu yerda");}}, 1000);}readFile("data.txt", function (error, data) {if (error) {console.log("Xatolik: " + error.message);return;}console.log("Ma'lumot: " + data);});
Callback har doim ikki argument bilan chaqiriladi: birinchisi — xatolik (agar bo'lmasa null), ikkinchisi — natija. Callback ichida avval xatolik borligini tekshirish odat tusiga kirgan.
💡 Key Idea
Bu naqsh — Chapter 18'dagi try/catchga o'xshash maqsadga xizmat qiladi, lekin asinxron kod uchun mo'ljallangan, chunki try/catch asinxron callback ichidagi xatolarni ushlay olmaydi (bu — keyingi bo'limda ko'rsatiladi).
script.jsJavaScripttry {setTimeout(function () {throw new Error("Xatolik!");}, 1000);} catch (error) {console.log("Ushlandi: " + error.message); // Bu HECH QACHON ishlamaydi!}
try bloki faqat darhol, sinxron tarzda bajariladigan kod ichidagi xatolarni ushlaydi. setTimeout ichidagi function — 1 soniyadan keyin, butunlay boshqa vaqtda chaqiriladi, o'shanda try bloki allaqachon "tugagan" (o'z ishini bajarib bo'lgan) bo'ladi.
code.textTEXTtry {setTimeout(...) → "rejalashtirildi va unutildi"} catch { ... } ← try bloki BU YERDA allaqachon tugagan... 1 soniyadan keyin ...setTimeout ichidagi kod ishga tushadi,lekin catch endi "eshitmaydi"
🔥 Important
Bu — asinxron dasturlashdagi eng muhim va ko'p xato qilinadigan tushunchalardan biri. Xatoni to'g'ri ushlash uchun, try/catchni callback function ichiga joylashtirish kerak:
script.jsJavaScriptsetTimeout(function () {try {throw new Error("Xatolik!");} catch (error) {console.log("Ushlandi: " + error.message); // Endi ishlaydi}}, 1000);
Task:
greetLater(name, callback) function yozing — u setTimeout orqali 1 soniyadan keyin callback("Salom, " + name) chaqirsin.
Required Concepts:
setTimeoutsetTimeout(() => callback("Salom, " + name), 1000);Task:
Error-first callback naqshidan foydalanib, divide(a, b, callback) function yozing — agar b === 0 bo'lsa, callback(new Error("Nolga bo'lib bo'lmaydi")), aks holda callback(null, a / b) chaqirsin.
Required Concepts:
readFile misolidan namuna oling.Task:
Uchta bosqichli "Callback Hell" simulyatsiyasini yozing: step1(callback) → 500ms kutib "natija1" beradi, step2(data, callback) → datani qabul qilib, 500ms kutib data + " + natija2" beradi, step3(data, callback) → xuddi shunday " + natija3" qo'shadi. Ularni ketma-ket, callback ichida callback qilib chaqiring va yakuniy natijani chiqaring.
Required Concepts:
setTimeoutscript.jsJavaScriptconsole.log("A");setTimeout(function () {console.log("B");}, 0);console.log("C");
🧠 Think first! Javobni ko'rishdan oldin kamida 30 soniya o'ylang.
<details> <summary>Answer</summary> A C BWhy?
Garchi setTimeoutning kutish vaqti 0 millisekund bo'lsa ham, u baribir asinxron hisoblanadi — u darhol emas, JavaScript'ning joriy sinxron kodi ("A", "C") to'liq tugagandan keyin ishga tushadi. Bu — Chapter 29'da (Event Loop) chuqur tushuntiriladigan xatti-harakat.
Quyidagi kodda muammo bor:
script.jsJavaScriptfunction fetchData(callback) {setTimeout(function () {callback({ name: "Test" });}, 1000);}let result;fetchData(function (data) {result = data;});console.log(result.name); // Xatolik!
Your Task:
Yechim: resultga bog'liq barcha kodni callback ichiga joylashtirish kerak:
</details>script.jsJavaScriptfunction fetchData(callback) {setTimeout(function () {callback({ name: "Test" });}, 1000);}fetchData(function (data) {console.log(data.name); // "Test" — to'g'ri ishlaydi});
try/catch — asinxron callback ichidagi xatolarni ushlamaydi, faqat sinxron kodni ushlaydi.setTimeout(fn, 0) ham asinxron — u sinxron koddan keyin ishga tushadi.script.jsJavaScriptfunction doSomethingAsync(callback) {setTimeout(function () {callback(null, "natija");}, 1000);}doSomethingAsync(function (error, result) {if (error) {console.log("Xatolik: " + error.message);return;}console.log(result);});
Mavzu bo‘yicha tushunchalaringizni interaktiv test orqali sinovdan o‘tkazing va natijalarni bilib oling.
Darslikda o‘rganilgan qoidalarga asosan real kod yozing, testlardan o‘tkazing va yechimlarni mustahkamlang.
Test Sinovi
Hali topshirilmagan (kamida 75% kerak)
Amaliy Masalalar
0 / 3 ta yechildi (kamida 75% kerak)
Dars sifati va mazmunini yaxshilash uchun o‘z haqqoniy bahoingizni qoldiring.
Mavzuni to‘liq o‘zlashtirish uchun test sinovi, amaliy kodlash va bog‘liq darslar
O‘z bilimingizni interaktiv test savollari orqali tekshiring va darhol xatolarni tahlil qiling.
Nazariyani real kod yozish bilan mustahkamlang, avtomatik testlardan o‘ting va XP to‘plang.
Kurs bo‘yicha keyingi va bog‘liq mavzular: