ES2017 async/await sintaksisi, async funksiyalar va doimiy Promise qaytarish qoidasi, await ketma-ketligi va parallellashtirish (Promise.all), try/catch orqali xatolarni ushlash va for...of da asinxronlik.
Chapter 27'da Promise'lar Callback Hell'ni qanday hal qilishini ko'rdik. async/await — ES2017'da qo'shilgan, Promise'lar ustiga qurilgan, asinxron kodni xuddi sinxron koddek yozish imkonini beruvchi sintaksis.
async — functionni asinxron deb belgilaydi, bu function har doim Promise qaytaradi.await — Promise tugashini kutadi, va uning natijasini to'g'ridan-to'g'ri qiymat sifatida qaytaradi (.then() yozmasdan).⏸️ await — bu "shu yerda pauza qiling, natija kelguncha kuting" degan buyruq, lekin dastur butunlay to'xtab qolmaydi — u faqat o'sha async function ichida "pauza" qiladi, boshqa kod (masalan, boshqa function'lar) baribir ishlayveradi.
script.jsJavaScript// Promise bilan (Chapter 27)function getUser() {return fetch("/api/user").then(response => response.json()).then(data => {console.log(data);}).catch(error => console.log(error));}
script.jsJavaScript// async/await bilan (xuddi shu mantiq, ancha tushunarli)async function getUser() {try {let response = await fetch("/api/user");let data = await response.json();console.log(data);} catch (error) {console.log(error);}}
Ikkala kod ham aynan bir xil ishlaydi, lekin async/await versiyasi xuddi oddiy, sinxron koddek o'qiladi — .then() zanjirlarisiz.
🔥 Important
await — faqat async function ichida ishlatilishi mumkin (yoki zamonaviy modul darajasida, "top-level await"). Oddiy function ichida await yozish — sintaksis xatoligiga olib keladi.
Bu — ko'pchilikni chalg'itadigan, lekin muhim qoida: async function hech qachon to'g'ridan-to'g'ri qiymat qaytarmaydi, u har doim shu qiymat bilan resolve bo'lgan Promise qaytaradi.
script.jsJavaScriptasync function getNumber() {return 42;}console.log(getNumber()); // Promise {<fulfilled>: 42} — son emas!getNumber().then(value => {console.log(value); // 42 — bu yerda haqiqiy qiymat});
getNumber() — 42ni to'g'ridan-to'g'ri qaytarmaydi, u Promise.resolve(42)ga teng natija qaytaradi. Haqiqiy qiymatni olish uchun .then() yoki boshqa async function ichida await kerak.
💡 Key Idea
async function yozish — aslida functionni avtomatik ravishda Promise qaytaradigan qilib "o'rab olish"ning qisqa yo'li.
awaitlarni ketma-ket yozish — har birini navbat bilan kutadi, bu esa ba'zida keraksiz sekinlikka olib kelishi mumkin.
script.jsJavaScriptasync function loadData() {let user = await getUser(); // 1 soniya kutadilet posts = await getPosts(); // yana 1 soniya kutadi (lekin user'ga bog'liq emas!)let comments = await getComments(); // yana 1 soniyaconsole.log(user, posts, comments);}// Umumiy vaqt: ~3 soniya
Nima uchun bu noto'g'ri (samarasiz)?
Agar getPosts() va getComments() — userga bog'liq bo'lmasa (ya'ni ular bir-biridan mustaqil ma'lumot olishsa), ularni ketma-ket kutishning hojati yo'q — ular parallel ishlashi mumkin edi.
script.jsJavaScriptasync function loadData() {let [user, posts, comments] = await Promise.all([getUser(),getPosts(),getComments()]);console.log(user, posts, comments);}// Umumiy vaqt: ~1 soniya (eng uzunisiga qarab)
code.textTEXTKetma-ket (sekin):getUser() ──1s──> getPosts() ──1s──> getComments() ──1s──>Jami: 3sParallel (tez):getUser() ──1s──┐getPosts() ──1s──┤→ hammasi birga tugaydigetComments() ──1s──┘Jami: 1s
⚠️ Common Mistake
awaitlarni avtomatik ravishda ketma-ket yozish — eng ko'p uchraydigan async/await xatosi. Har doim o'zingizdan so'rang: "bu amallar bir-biriga bog'liqmi, yoki mustaqilmi?" Agar mustaqil bo'lsa — Promise.all() ishlatish kerak.
🔗 Connection
Bu — Chapter 27.6'da o'rgangan Promise.all()ning async/await bilan birgalikda ishlatilishi.
async/await bilan ishlaganda, Chapter 18'da o'rgangan oddiy try/catch ishlatiladi — bu Callback'lardagidek maxsus naqshlar (error-first) yoki Promise'lardagidek .catch() shart emas.
script.jsJavaScriptasync function fetchUserData(id) {try {let response = await fetch(`/api/users/${id}`);if (!response.ok) {throw new Error("Server xatoligi: " + response.status);}let data = await response.json();return data;} catch (error) {console.log("Xatolik yuz berdi: " + error.message);return null;}}
Bu — Chapter 26.5'da ko'rgan "try/catch callback ichidagi xatoni ushlamaydi" muammosining hal qilingan versiyasi: async/await bilan awaitlangan Promise reject bo'lsa, bu xatolik oddiy throw kabi ishlaydi va try/catch uni to'g'ri ushlaydi.
🔥 Important
Aynan shu xususiyat — async/awaitning eng katta afzalliklaridan biri: asinxron kod bilan ishlashda, sinxron kod uchun tanish bo'lgan try/catch mexanizmidan foydalanish mumkin bo'ladi.
await — oddiy for...of loop ichida to'g'ridan-to'g'ri ishlatilishi mumkin, bu esa ketma-ket asinxron amallarni oson yozish imkonini beradi.
script.jsJavaScriptasync function processUsers(userIds) {for (let id of userIds) {let user = await getUser(id);console.log(user.name);}}
⚠️ Common Mistake
awaitni forEach() ichida ishlatish — kutilganidek ishlamaydi, chunki forEach() awaitni "kutmaydi":
script.jsJavaScript// ❌ Noto'g'riuserIds.forEach(async (id) => {let user = await getUser(id);console.log(user.name);});// Barcha so'rovlar deyarli bir vaqtda "otiladi", tartib kafolatlanmaydi
✅ To'g'ri — agar ketma-ketlik muhim bo'lsa, oddiy for...of ishlatiladi (yuqoridagi misolda ko'rgandek).
Task:
getGreeting(name) nomli async function yozing — u setTimeout orqali (Promise ichiga o'rab) 1 soniyadan keyin "Salom, " + nameni qaytarsin. Uni boshqa async function ichida await bilan chaqiring.
Required Concepts:
async/awaitsetTimeoutni Promise bilan o'rab oling: new Promise(resolve => setTimeout(() => resolve(...), 1000)).Task:
Chapter 27.5'dagi getUser/getPosts Promise function'laridan foydalanib, ularni async/await va try/catch bilan qayta yozing.
Required Concepts:
async/awaittry/catchlet user = await getUser(1); let posts = await getPosts(user.id);Task:
3 ta mustaqil (bir-biriga bog'liq bo'lmagan) Promise qaytaruvchi function yarating (turli kutish vaqtlari bilan). Ularni avval ketma-ket (await bilan birma-bir), keyin parallel (Promise.all() bilan) chaqirib, ikkala usulning umumiy ishlash vaqtini solishtiring (Date.now() yordamida, Chapter 20).
Required Concepts:
async/awaitPromise.all()Date.now()ni saqlab, farqini hisoblang.script.jsJavaScriptasync function test() {console.log("1");await new Promise(resolve => setTimeout(resolve, 1000));console.log("2");}console.log("A");test();console.log("B");
🧠 Think first! Javobni ko'rishdan oldin kamida 30 soniya o'ylang.
<details> <summary>Answer</summary> A 1 B (1 soniyadan keyin) 2Why?
test() chaqirilganda, uning ichidagi kod awaitgacha sinxron tarzda ishlaydi — shuning uchun "1" darhol chiqadi. await uchraganda, function "pauza" qiladi va boshqaruvni tashqi kodga qaytaradi, shuning uchun "B" "1"dan keyin, lekin "2"dan oldin chiqadi. 1 soniyadan keyin, Promise hal qilingach, test() davom etib "2"ni chiqaradi.
Quyidagi kodda muammo bor:
script.jsJavaScriptasync function getTotalPrice(itemIds) {let total = 0;itemIds.forEach(async (id) => {let price = await getPrice(id);total += price;});return total; // Har doim 0 qaytaradi!}
Your Task:
total har doim 0 qaytarishini tushuntiring.for...of yordamida tuzating.Yechim:
</details>script.jsJavaScriptasync function getTotalPrice(itemIds) {let total = 0;for (let id of itemIds) {let price = await getPrice(id);total += price;}return total; // Endi to'g'ri ishlaydi}
async function — har doim Promise qaytaradi, garchi ichida oddiy qiymat return qilinsa ham.await — Promise tugashini kutadi va uning natijasini to'g'ridan-to'g'ri qiymat sifatida beradi.try/catch — asinxron xatolarni sinxron kodga o'xshash tarzda boshqarish imkonini beradi.await qilish — samarasiz, Promise.all() afzalroq.forEach() ichida await ishlamaydi — for...of ishlatish kerak.async/await — Promise ustiga qurilgan, asinxron kodni sinxrondek o'qilishini ta'minlaydigan sintaksis.Promise.all()) bajarish tezroq.try/catch ishlatiladi.awaitni forEach() ichida emas, for...of ichida ishlating.async function'ning natijasini olish uchun har doim await yoki .then() kerak.script.jsJavaScriptasync function fetchData() {try {let result = await someAsyncOperation();return result;} catch (error) {console.log(error.message);}}// Parallel bajarishasync function loadAll() {let [a, b, c] = await Promise.all([taskA(), taskB(), taskC()]);}// Ketma-ket loopasync function processAll(items) {for (let item of items) {await processItem(item);}}
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: