From 54ec3cd0bb7b2ab4c96ac47fb9f0e26f6673b7a8 Mon Sep 17 00:00:00 2001 From: abek01sulaymonov Date: Mon, 13 Oct 2025 18:16:36 +0500 Subject: [PATCH] fix: fixed direct translation of phrases --- 1-js/11-async/02-promise-basics/article.md | 235 +++++++++--------- 1-js/11-async/03-promise-chaining/article.md | 158 +++++------- .../04-promise-error-handling/article.md | 30 +-- 2-ui/index.md | 2 +- 4 files changed, 198 insertions(+), 227 deletions(-) diff --git a/1-js/11-async/02-promise-basics/article.md b/1-js/11-async/02-promise-basics/article.md index 45d15eb3d..6a9c3ac9b 100644 --- a/1-js/11-async/02-promise-basics/article.md +++ b/1-js/11-async/02-promise-basics/article.md @@ -9,49 +9,49 @@ Hamma xursand: siz, chunki odamlar sizni endi bezovta qilmaydi, va muxlislar, ch Bu dasturlashda tez-tez uchratiladigan narsalar uchun hayotiy o'xshashlik: 1. Nimadir qiladigan va vaqt talab qiladigan "ishlab chiqaruvchi kod". Masalan, ma'lumotlarni tarmoq orqali yuklaydigan kod. Bu "qo'shiqchi". -2. "Ishlab chiqaruvchi kod" ning natijasini tayyor bo'lganda xohlaydigan "iste'mol qiluvchi kod". Ko'plab funktsiyalar bu natijaga muhtoj bo'lishi mumkin. Bular "muxlislar". -3. *Promise* - bu "ishlab chiqaruvchi kod" va "iste'mol qiluvchi kod" ni bog'laydigan maxsus JavaScript objekt. Bizning o'xshashligimizda: bu "obuna ro'yxati". "Ishlab chiqaruvchi kod" va'da qilingan natijani ishlab chiqarish uchun qancha vaqt kerak bo'lsa, shuncha vaqt oladi va "promise" bu natijani tayyor bo'lganda barcha obuna bo'lgan kodlarga taqdim etadi. +2. "Ishlab chiqaruvchi kod"ning natijasini tayyor bo'lganda xohlaydigan "iste'mol qiluvchi kod". Ko'plab funktsiyalar bu natijaga muhtoj bo'lishi mumkin. Bular "muxlislar". +3. **Promise** - bu "ishlab chiqaruvchi kod" va "iste'mol qiluvchi kod"ni bog'laydigan maxsus JavaScript obyekti. Bizning o'xshashligimizda: bu "obuna ro'yxati". "Ishlab chiqaruvchi kod" va'da qilingan natijani ishlab chiqarish uchun qancha vaqt kerak bo'lsa, shuncha vaqt oladi va **promise** bu natijani tayyor bo'lganda barcha obuna bo'lgan kodlarga taqdim etadi. -O'xshashlik unchalik aniq emas, chunki JavaScript promise-lari oddiy obuna ro'yxatidan murakkabroq: ularda qo'shimcha xususiyatlar va cheklovlar bor. Lekin boshlash uchun yaxshi. +O'xshashlik unchalik aniq emas, chunki JavaScript promise'lari oddiy obuna ro'yxatidan murakkabroq: ularda qo'shimcha xususiyatlar va cheklovlar bor. Lekin boshlash uchun yaxshi. -Promise objekt uchun konstruktor sintaksisi: +Promise obyekti uchun constructor sintaksisi: ```js -let promise = new Promise(function(resolve, reject) { - // executor (ishlab chiqaruvchi kod, "qo'shiqchi") +let promise = new Promise(function (resolve, reject) { + // executor (ishlab chiqaruvchi kod) }); ``` -`new Promise` ga uzatilgan funktsiya *executor* deb ataladi. `new Promise` yaratilganda, executor avtomatik ravishda ishlaydi. U oxir-oqibat natijani ishlab chiqarishi kerak bo'lgan ishlab chiqaruvchi kodini o'z ichiga oladi. Yuqoridagi o'xshashlikda: executor "qo'shiqchi". +`new Promise`ga uzatilgan funktsiya **executor** deb ataladi. `new Promise` yaratilganda, executor avtomatik ravishda ishlaydi. U oxir-oqibat natijani ishlab chiqarishi kerak bo'lgan ishlab chiqaruvchi kodini o'z ichiga oladi. Yuqoridagi o'xshashlikda: executor "qo'shiqchi". -Uning `resolve` va `reject` argumentlari JavaScript ning o'zi tomonidan taqdim etilgan callbacklar. Bizning kodimiz faqat executor ichida. +Uning `resolve` va `reject` argumentlari JavaScript'ning o'zi tomonidan taqdim etilgan callback'lar. Bizning kodimiz faqat executor ichida. -Executor natijani olganda, tez bo'lsin yoki kech, muhim emas, u ushbu callbacklardan birini chaqirishi kerak: +Executor natijani olganda, tez bo'lsin yoki kech, muhim emas, u ushbu callback'lardan birini chaqirishi kerak: - `resolve(value)` — agar ish muvaffaqiyatli tugatilgan bo'lsa, `value` natijasi bilan. -- `reject(error)` — agar xato yuz bergan bo'lsa, `error` xato objekti. +- `reject(error)` — agar xato yuz bergan bo'lsa, `error` xato obyekti. -Xulosa qilish uchun: executor avtomatik ravishda ishlaydi va ishni bajarishga harakat qiladi. Harakat tugaganda, muvaffaqiyatli bo'lsa `resolve` ni, xato bo'lsa `reject` ni chaqiradi. +Xulosa qilish uchun: executor avtomatik ravishda ishlaydi va ishni bajarishga harakat qiladi. Harakat tugaganda, muvaffaqiyatli bo'lsa `resolve`ni, xato bo'lsa `reject`ni chaqiradi. -`new Promise` konstruktor tomonidan qaytarilgan `promise` objekti quyidagi ichki xususiyatlarga ega: +`new Promise` constructor tomonidan qaytarilgan `promise` obyekti quyidagi ichki property'larga ega: -- `state` — dastlab `"pending"`, keyin `resolve` chaqirilganda `"fulfilled"` ga yoki `reject` chaqirilganda `"rejected"` ga o'zgaradi. -- `result` — dastlab `undefined`, keyin `resolve(value)` chaqirilganda `value` ga yoki `reject(error)` chaqirilganda `error` ga o'zgaradi. +- `state` — dastlab `"pending"`, keyin `resolve` chaqirilganda `"fulfilled"`ga yoki `reject` chaqirilganda `"rejected"`ga o'zgaradi. +- `result` — dastlab `undefined`, keyin `resolve(value)` chaqirilganda `value`ga yoki `reject(error)` chaqirilganda `error`ga o'zgaradi. -Shunday qilib executor oxir-oqibat `promise` ni quyidagi holatlardan biriga o'tkazadi: +Shunday qilib executor oxir-oqibat `promise`ni quyidagi holatlardan biriga o'tkazadi: ![](promise-resolve-reject.svg) Keyinroq biz "muxlislar" qanday qilib bu o'zgarishlarga obuna bo'lishlarini ko'ramiz. -Mana promise konstruktor va vaqt talab qiladigan "ishlab chiqaruvchi kod" bilan oddiy executor funktsiyaning misoli (`setTimeout` orqali): +Mana promise constructor va vaqt talab qiladigan "ishlab chiqaruvchi kod" bilan oddiy executor funktsiyaning misoli (`setTimeout` orqali): ```js let promise = new Promise(function(resolve, reject) { // funktsiya promise yaratilganda avtomatik ravishda bajariladi // 1 soniyadan keyin ish "done" natijasi bilan tugaganligini bildirish - setTimeout(() => *!*resolve("done")*/!*, 1000); + setTimeout(() => resolve("done"), 1000); }); ``` @@ -60,33 +60,33 @@ Yuqoridagi kodni ishga tushirish orqali ikkita narsani ko'rishimiz mumkin: 1. Executor avtomatik va darhol chaqiriladi (`new Promise` tomonidan). 2. Executor ikkita argument oladi: `resolve` va `reject`. Bu funktsiyalar JavaScript mexanizmi tomonidan oldindan belgilangan, shuning uchun biz ularni yaratishimiz shart emas. Tayyor bo'lganda ulardan faqat birini chaqirishimiz kerak. - Bir soniyalik "qayta ishlash"dan keyin executor natijani ishlab chiqarish uchun `resolve("done")` ni chaqiradi. Bu `promise` objektining holatini o'zgartiradi: + Bir soniyalik "qayta ishlash"dan keyin executor natijani ishlab chiqarish uchun `resolve("done")`ni chaqiradi. Bu `promise` obyektining holatini o'zgartiradi: - ![](promise-resolve-1.svg) + ![](promise-resolve-1.svg) -Bu muvaffaqiyatli ish tugallash, "bajarilgan promise" ning misoli edi. +Bu muvaffaqiyatli ish tugallash, "bajarilgan promise"ning misoli edi. -Endi executor promise ni xato bilan rad etish misoli: +Endi executor promise'ni xato bilan rad etish misoli: ```js let promise = new Promise(function(resolve, reject) { // 1 soniyadan keyin ish xato bilan tugaganligini bildirish - setTimeout(() => *!*reject(new Error("Whoops!"))*/!*, 1000); + setTimeout(() => reject(new Error("Whoops!")), 1000); }); ``` -`reject(...)` ga chaqiruv promise objektini `"rejected"` holatiga o'tkazadi: +`reject(...)`ga chaqiruv promise obyektini `"rejected"` holatiga o'tkazadi: ![](promise-reject-1.svg) -Xulosa qilish uchun, executor ish bajarishi kerak (odatda vaqt talab qiladigan narsa) va keyin tegishli promise objektning holatini o'zgartirish uchun `resolve` yoki `reject` ni chaqirishi kerak. +Xulosa qilish uchun, executor ish bajarishi kerak (odatda vaqt talab qiladigan narsa) va keyin tegishli promise obyektning holatini o'zgartirish uchun `resolve` yoki `reject`ni chaqirishi kerak. -Hal qilingan yoki rad etilgan promise "settled" deb ataladi, dastlabki "pending" promise dan farqli o'laroq. +Resolved yoki rejected promise **"settled"** deb ataladi, dastlabki `"pending"` promise'dan farqli o'laroq. ````smart header="Faqat bitta natija yoki xato bo'lishi mumkin" -Executor faqat bitta `resolve` yoki bitta `reject` ni chaqirishi kerak. Har qanday holat o'zgarishi yakuniy. +Executor faqat bitta `resolve` yoki bitta `reject`ni chaqirishi kerak. Har qanday holat o'zgarishi yakuniy. -`resolve` va `reject` ning barcha keyingi chaqiruvlari e'tiborga olinmaydi: +`resolve` va `reject`ning barcha keyingi chaqiruvlari e'tiborga olinmaydi: ```js let promise = new Promise(function(resolve, reject) { @@ -104,12 +104,12 @@ G'oya shundaki, executor tomonidan bajarilgan ish faqat bitta natija yoki xatoga Shuningdek, `resolve`/`reject` faqat bitta argumentni kutadi (yoki hech birini) va qo'shimcha argumentlarni e'tiborsiz qoldiradi. ```` -```smart header="`Error` objektlari bilan rad etish" -Biror narsa noto'g'ri ketganda, executor `reject` ni chaqirishi kerak. Bu har qanday turdagi argument bilan qilinishi mumkin (`resolve` kabi). Lekin `Error` objektlarini (yoki `Error` dan meros olgan objektlarni) ishlatish tavsiya etiladi. Buning sababi tez orada aniq bo'ladi. +```smart header="`Error` obyektlari bilan rad etish" +Biror narsa noto'g'ri ketganda, executor `reject`ni chaqirishi kerak. Bu har qanday turdagi argument bilan qilinishi mumkin (`resolve` kabi). Lekin `Error` obyektlarini (yoki `Error`dan meros olgan obyektlarni) ishlatish tavsiya etiladi. Buning sababi tez orada aniq bo'ladi. ``` ````smart header="Darhol `resolve`/`reject` chaqirish" -Amalda executor odatda biror narsani asinxron qiladi va bir muncha vaqtdan keyin `resolve`/`reject` ni chaqiradi, lekin bu majburiy emas. Biz `resolve` yoki `reject` ni darhol ham chaqirishimiz mumkin: +Amalda executor odatda biror narsani asinxron qiladi va bir muncha vaqtdan keyin `resolve`/`reject`ni chaqiradi, lekin bu majburiy emas. Biz `resolve` yoki `reject`ni darhol ham chaqirishimiz mumkin: ```js let promise = new Promise(function(resolve, reject) { @@ -118,57 +118,55 @@ let promise = new Promise(function(resolve, reject) { }); ``` -Masalan, bu ishni boshlashga harakat qilganimizda, lekin hamma narsa allaqachon tugallangan va keshlanganligini ko'rganimizda sodir bo'lishi mumkin. +Masalan, bu ishni boshlashga harakat qilganimizda, lekin hamma narsa allaqachon tugallangan va keshlangan bo'lsa sodir bo'lishi mumkin. -Bu yaxshi. Biz darhol hal qilingan promise ga ega bo'lamiz. +Bu yaxshi. Biz darhol resolved promise'ga ega bo'lamiz. ```` -```smart header="`state` va `result` ichki xususiyatlar" -Promise objektining `state` va `result` xususiyatlari ichki. Biz ularga to'g'ridan-to'g'ri kira olmaymiz. Buning uchun `.then`/`.catch`/`.finally` metodlaridan foydalanishimiz mumkin. Ular quyida tasvirlangan. +```smart header="`state` va `result` ichki property'lar" +Promise obyektining `state` va `result` property'lari ichki. Biz ularga to'g'ridan-to'g'ri kira olmaymiz. Buning uchun `.then`/`.catch`/`.finally` metodlaridan foydalanishimiz mumkin. Ular quyida tasvirlangan. ``` ## Iste'molchilar: then, catch -Promise objekt executor ("ishlab chiqaruvchi kod" yoki "qo'shiqchi") va natija yoki xatoni qabul qiladigan iste'mol qiluvchi funktsiyalar ("muxlislar") o'rtasidagi bog'lanish vazifasini bajaradi. Iste'mol qiluvchi funktsiyalar `.then` va `.catch` metodlari yordamida ro'yxatga olinishi (obuna bo'lishi) mumkin. +Promise obyekti executor ("ishlab chiqaruvchi kod" yoki "qo'shiqchi") va natija yoki xatoni qabul qiladigan iste'mol qiluvchi funktsiyalar ("muxlislar") o'rtasidagi bog'lanish vazifasini bajaradi. Iste'mol qiluvchi funktsiyalar `.then` va `.catch` metodlari yordamida ro'yxatga olinishi (obuna bo'lishi) mumkin. ### then -Eng muhim, asosiy biri `.then` dir. +Eng muhim, asosiy biri `.then`dir. Sintaksis: ```js promise.then( - function(result) { *!*/* muvaffaqiyatli natijani hal qilish */*/!* }, - function(error) { *!*/* xatoni hal qilish */*/!* } + function(result) { /* muvaffaqiyatli natijani hal qilish */ }, + function(error) { /* xatoni hal qilish */ } ); ``` -`.then` ning birinchi argumenti promise hal qilinganda ishlaydigan va natijani qabul qiladigan funktsiya. +`.then`ning birinchi argumenti promise resolved bo'lganda ishlaydigan va natijani qabul qiladigan funktsiya. -`.then` ning ikkinchi argumenti promise rad etilganda ishlaydigan va xatoni qabul qiladigan funktsiya. +`.then`ning ikkinchi argumenti promise rejected bo'lganda ishlaydigan va xatoni qabul qiladigan funktsiya. -Masalan, mana muvaffaqiyatli hal qilingan promise ga javob: +Masalan, mana muvaffaqiyatli resolved promise'ga javob: -```js run +```js let promise = new Promise(function(resolve, reject) { setTimeout(() => resolve("done!"), 1000); }); // resolve .then dagi birinchi funktsiyani ishga tushiradi promise.then( -*!* result => alert(result), // 1 soniyadan keyin "done!" ni ko'rsatadi -*/!* error => alert(error) // ishlamaydi ); ``` Birinchi funktsiya bajarildi. -Va rad etish holatida, ikkinchisi: +Va rejection holatida, ikkinchisi: -```js run +```js let promise = new Promise(function(resolve, reject) { setTimeout(() => reject(new Error("Whoops!")), 1000); }); @@ -176,50 +174,44 @@ let promise = new Promise(function(resolve, reject) { // reject .then dagi ikkinchi funktsiyani ishga tushiradi promise.then( result => alert(result), // ishlamaydi -*!* error => alert(error) // 1 soniyadan keyin "Error: Whoops!" ni ko'rsatadi -*/!* ); ``` -Agar biz faqat muvaffaqiyatli tugashlar bilan qiziqsak, u holda `.then` ga faqat bitta funktsiya argumentini taqdim etishimiz mumkin: +Agar biz faqat muvaffaqiyatli tugashlar bilan qiziqsak, u holda `.then`ga faqat bitta funktsiya argumentini taqdim etishimiz mumkin: -```js run +```js let promise = new Promise(resolve => { setTimeout(() => resolve("done!"), 1000); }); -*!* promise.then(alert); // 1 soniyadan keyin "done!" ni ko'rsatadi -*/!* ``` ### catch -Agar biz faqat xatolar bilan qiziqsak, u holda birinchi argument sifatida `null` dan foydalanishimiz mumkin: `.then(null, errorHandlingFunction)`. Yoki `.catch(errorHandlingFunction)` dan foydalanishimiz mumkin, bu aynan bir xil: +Agar biz faqat xatolar bilan qiziqsak, u holda birinchi argument sifatida `null`dan foydalanishimiz mumkin: `.then(null, errorHandlingFunction)`. Yoki `.catch(errorHandlingFunction)`dan foydalanishimiz mumkin, bu aynan bir xil: -```js run +```js let promise = new Promise((resolve, reject) => { setTimeout(() => reject(new Error("Whoops!")), 1000); }); -*!* // .catch(f) promise.then(null, f) bilan bir xil promise.catch(alert); // 1 soniyadan keyin "Error: Whoops!" ni ko'rsatadi -*/!* ``` -`.catch(f)` chaqiruvi `.then(null, f)` ning to'liq analogi, bu faqat qisqartma. +`.catch(f)` chaqiruvi `.then(null, f)`ning to'liq analogi, bu faqat qisqartma. ## Tozalash: finally -Oddiy `try {...} catch {...}` da `finally` bo'limi bo'lgani kabi, promise-larda ham `finally` bor. +Oddiy `try {...} catch {...}`da `finally` bo'limi bo'lgani kabi, promise'larda ham `finally` bor. -`.finally(f)` chaqiruvi `.then(f, f)` ga o'xshash ma'noda, ya'ni `f` har doim ishlaydi, promise bajarilganda: hal qilingan yoki rad etilgan bo'lsin. +`.finally(f)` chaqiruvi `.then(f, f)`ga o'xshash ma'noda, ya'ni `f` har doim ishlaydi, promise bajarilganda: resolved yoki rejected bo'lsin. -`finally` ning g'oyasi oldingi amallar tugagandan keyin tozalash/yakunlash bajarish uchun handler o'rnatishdir. +`finally`ning g'oyasi oldingi amallar tugagandan keyin tozalash/yakunlash bajarish uchun handler o'rnatishdir. -Masalan, yuklanish indikatorlarini to'xtatish, endi kerak bo'lmagan ulanishlarni yopish va boshqalar. +Masalan, loading indikatorlarini to'xtatish, endi kerak bo'lmagan ulanishlarni yopish va boshqalar. Buni ziyofat yakunlovchisi sifatida tasavvur qiling. Ziyofat yaxshi yoki yomon bo'lishidan, qancha do'stlar ishtirok etganidan qat'i nazar, biz baribir undan keyin tozalash qilishimiz kerak (yoki hech bo'lmaganda qilishimiz kerak). @@ -229,110 +221,111 @@ Kod shunday ko'rinishi mumkin: new Promise((resolve, reject) => { /* vaqt talab qiladigan biror narsa qiling, keyin resolve yoki reject ni chaqiring */ }) -*!* // promise bajarilganda ishlaydi, muvaffaqiyatli yoki yo'qligi muhim emas - .finally(() => yuklanish indikatorini to'xtatish) - // shuning uchun yuklanish indikatori har doim davom etishdan oldin to'xtatiladi -*/!* + .finally(() => loading indikatorini to'xtatish) + // shuning uchun loading indikatori har doim davom etishdan oldin to'xtatiladi .then(result => natijani ko'rsatish, err => xatoni ko'rsatish) ``` -E'tibor bering, `finally(f)` aynan `then(f,f)` ning taxallusi emas. +E'tibor bering, `finally(f)` aynan `then(f,f)`ning taxallusi emas. Muhim farqlar bor: -1. `finally` handleri argumentlarga ega emas. `finally` da promise muvaffaqiyatli yoki yo'qligini bilmaymiz. Bu normal, chunki bizning vazifamiz odatda "umumiy" yakunlash tartib-qoidalarini bajarishdir. +1. `finally` handler argumentlarga ega emas. `finally`da biz promise muvaffaqiyatli yoki yo'qligini bilmaymiz. Bu normal, chunki bizning vazifamiz odatda "umumiy" yakunlash tartib-qoidalarini bajarishdir. - Yuqoridagi misolga qarang: ko'rib turganingizdek, `finally` handleri argumentlarga ega emas va promise natijasi keyingi handler tomonidan hal qilinadi. -2. `finally` handleri natija yoki xatoni keyingi mos handlerga "o'tkazadi". + Yuqoridagi misolga qarang: ko'rib turganingizdek, `finally` handler argumentlarga ega emas va promise natijasi keyingi handler tomonidan hal qilinadi. - Masalan, bu yerda natija `finally` orqali `then` ga o'tkaziladi: +2. `finally` handler natija yoki xatoni keyingi mos handlerga "o'tkazadi". - ```js run - new Promise((resolve, reject) => { - setTimeout(() => resolve("value"), 2000); - }) - .finally(() => alert("Promise tayyor")) // birinchi bo'lib ishga tushadi - .then(result => alert(result)); // <-- .then "value" ni ko'rsatadi - ``` + Masalan, bu yerda natija `finally` orqali `then`ga o'tkaziladi: - Ko'rib turganingizdek, birinchi promise tomonidan qaytarilgan `value` `finally` orqali keyingi `then` ga o'tkaziladi. + ```js + new Promise((resolve, reject) => { + setTimeout(() => resolve("value"), 2000); + }) + .finally(() => alert("Promise tayyor")) // birinchi bo'lib ishga tushadi + .then(result => alert(result)); // <-- .then "value" ni ko'rsatadi + ``` - Bu juda qulay, chunki `finally` promise natijasini qayta ishlash uchun mo'ljallanmagan. Aytilganidek, bu natija qanday bo'lishidan qat'i nazar, umumiy tozalash qilish joyi. + Ko'rib turganingizdek, birinchi promise tomonidan qaytarilgan `value` `finally` orqali keyingi `then`ga o'tkaziladi. - Va mana xato misoli, uni `finally` orqali `catch` ga qanday o'tkazilishini ko'rish uchun: + Bu juda qulay, chunki `finally` promise natijasini qayta ishlash uchun mo'ljallanmagan. Aytilganidek, bu natija qanday bo'lishidan qat'i nazar, umumiy tozalash qilish joyi. - ```js run - new Promise((resolve, reject) => { - throw new Error("error"); - }) - .finally(() => alert("Promise tayyor")) // birinchi bo'lib ishga tushadi - .catch(err => alert(err)); // <-- .catch xatoni ko'rsatadi - ``` + Va mana xato misoli, uni `finally` orqali `catch`ga qanday o'tkazilishini ko'rish uchun: -3. `finally` handleri ham hech narsa qaytarmasligi kerak. Agar qaytarsa, qaytarilgan qiymat jimgina e'tiborsiz qolinadi. + ```js + new Promise((resolve, reject) => { + throw new Error("error"); + }) + .finally(() => alert("Promise tayyor")) // birinchi bo'lib ishga tushadi + .catch(err => alert(err)); // <-- .catch xatoni ko'rsatadi + ``` - Bu qoidaning yagona istisnosi `finally` handleri xato tashlaganda. Keyin bu xato oldingi natija o'rniga keyingi handlerga boradi. +3. `finally` handler ham hech narsa qaytarmasligi kerak. Agar qaytarsa, qaytarilgan qiymat jimgina e'tiborsiz qolinadi. + + Bu qoidaning yagona istisnosi `finally` handler xato tashlaganda. Keyin bu xato oldingi natija o'rniga keyingi handlerga boradi. Xulosa qilish uchun: -- `finally` handleri oldingi handlerning natijasini olmaydi (argumentlari yo'q). Bu natija o'rniga keyingi mos handlerga o'tkaziladi. -- Agar `finally` handleri biror narsa qaytarsa, u e'tiborsiz qolinadi. -- `finally` xato tashlaganda, bajarilish eng yaqin xato handlerga boradi. +- `finally` handler oldingi handlerning natijasini olmaydi (argumentlari yo'q). Bu natija o'rniga keyingi mos handlerga o'tkaziladi. +- Agar `finally` handler biror narsa qaytarsa, u e'tiborsiz qolinadi. +- `finally` xato tashlaganda, bajarilish eng yaqin error handlerga boradi. -Bu xususiyatlar foydali va agar biz `finally` ni mo'ljallangan tarzda ishlatsak, ya'ni umumiy tozalash tartib-qoidalari uchun, narsalarni to'g'ri ishlashiga yordam beradi. +Bu xususiyatlar foydali va agar biz `finally`ni mo'ljallangan tarzda ishlatsak, ya'ni umumiy tozalash tartib-qoidalari uchun, narsalarni to'g'ri ishlashiga yordam beradi. -````smart header="Biz hal qilingan promise-larga handlerlarni biriktira olamiz" -Agar promise kutilayotgan bo'lsa, `.then/catch/finally` handlerlari uning natijasini kutadi. +````smart header="Biz resolved promise'larga handlerlarni biriktira olamiz" +Agar promise kutilayotgan bo'lsa (pending), `.then/catch/finally` handlerlari uning natijasini kutadi. -Ba'zan promise ga handler qo'shganimizda u allaqachon hal qilingan bo'lishi mumkin. +Ba'zan promise'ga handler qo'shganimizda u allaqachon resolved bo'lgan bo'lishi mumkin. Bunday holatda, bu handlerlar shunchaki darhol ishlaydi: -```js run -// promise yaratilishi bilanoq darhol hal qilinadi +```js +// promise yaratilishi bilanoq darhol resolved bo'ladi let promise = new Promise(resolve => resolve("done!")); promise.then(alert); // done! (hozir ko'rinadi) ``` -E'tibor bering, bu promise-larni haqiqiy hayotdagi "obuna ro'yxati" stsenariyasidan kuchliroq qiladi. Agar qo'shiqchi allaqachon qo'shiqni chiqargan bo'lsa va keyin kimdir obuna ro'yxatiga ro'yxatdan o'tsa, ular bu qo'shiqni olmaydi. Haqiqiy hayotda obuna voqea oldidan amalga oshirilishi kerak. +E'tibor bering, bu promise'larni haqiqiy hayotdagi "obuna ro'yxati" stsenariyasidan kuchliroq qiladi. Agar qo'shiqchi allaqachon qo'shiqni chiqargan bo'lsa va keyin kimdir obuna ro'yxatiga ro'yxatdan o'tsa, ular bu qo'shiqni olmaydi. Haqiqiy hayotda obuna voqea oldidan amalga oshirilishi kerak. -Promise-lar yanada moslashuvchan. Biz istalgan vaqtda handlerlarni qo'shishimiz mumkin: agar natija allaqachon mavjud bo'lsa, ular shunchaki bajariladi. +Promise'lar yanada moslashuvchan. Biz istalgan vaqtda handlerlarni qo'shishimiz mumkin: agar natija allaqachon mavjud bo'lsa, ular shunchaki bajariladi. ```` ## Misol: loadScript [#loadscript] -Keyinchalik, promise-lar asinxron kodni yozishda qanday yordam berishining ko'proq amaliy misollarini ko'raylik. +Keyinchalik, promise'lar asinxron kodni yozishda qanday yordam berishining ko'proq amaliy misollarini ko'raylik. -Bizda oldingi bobdan skriptni yuklash uchun `loadScript` funktsiyasi bor. +Bizda oldingi bobdan skript yuklash uchun `loadScript` funktsiyasi bor. Mana callback-asosidagi variant, uni esga olish uchun: ```js function loadScript(src, callback) { - let script = document.createElement('script'); + let script = document.createElement("script"); script.src = src; script.onload = () => callback(null, script); - script.onerror = () => callback(new Error(`${src} uchun skript yuklash xatosi`)); + script.onerror = () => + callback(new Error(`${src} uchun skript yuklash xatosi`)); document.head.append(script); } ``` -Uni Promise-lar yordamida qayta yozaylik. +Uni Promise'lar yordamida qayta yozaylik. -Yangi `loadScript` funktsiyasi callback talab qilmaydi. Buning o'rniga, u yuklash tugallanganda hal qilinuvchi Promise objektini yaratadi va qaytaradi. Tashqi kod unga `.then` yordamida handlerlar (obuna funktsiyalar) qo'shishi mumkin: +Yangi `loadScript` funktsiyasi callback talab qilmaydi. Buning o'rniga, u yuklash tugallanganda resolved bo'ladigan Promise obyektini yaratadi va qaytaradi. Tashqi kod unga `.then` yordamida handlerlar (obuna funktsiyalari) qo'shishi mumkin: -```js run +```js function loadScript(src) { - return new Promise(function(resolve, reject) { - let script = document.createElement('script'); + return new Promise(function (resolve, reject) { + let script = document.createElement("script"); script.src = src; script.onload = () => resolve(script); - script.onerror = () => reject(new Error(`${src} uchun skript yuklash xatosi`)); + script.onerror = () => + reject(new Error(`${src} uchun skript yuklash xatosi`)); document.head.append(script); }); @@ -341,22 +334,24 @@ function loadScript(src) { Foydalanish: -```js run -let promise = loadScript("https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"); +```js +let promise = loadScript( + "https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js" +); promise.then( - script => alert(`${script.src} yuklandi!`), - error => alert(`Xato: ${error.message}`) + (script) => alert(`${script.src} yuklandi!`), + (error) => alert(`Xato: ${error.message}`) ); -promise.then(script => alert('Boshqa handler...')); +promise.then((script) => alert("Boshqa handler...")); ``` Biz darhol callback-asosidagi naqshdan bir nechta afzalliklarni ko'rishimiz mumkin: -| Promise-lar | Callbacklar | -|----------|-----------| -| Promise-lar bizga narsalarni tabiiy tartibda qilish imkonini beradi. Birinchidan, biz `loadScript(script)` ni ishga tushiramiz va `.then` natija bilan nima qilishni yozamiz. | Biz `loadScript(script, callback)` ni chaqirishda `callback` funktsiyasiga ega bo'lishimiz kerak. Boshqacha qilib aytganda, `loadScript` chaqirilgunga *qadar* natija bilan nima qilishni bilishimiz kerak. | -| Biz Promise da `.then` ni xohlaganimizcha ko'p marta chaqirishimiz mumkin. Har safar biz yangi "muxlis", yangi obuna funktsiyasini "obuna ro'yxati"ga qo'shyapmiz. Bu haqida ko'proq keyingi bobda: [](info:promise-chaining). | Faqat bitta callback bo'lishi mumkin. | +| Promise'lar | Callback'lar | +|-------------|--------------| +| Promise'lar bizga narsalarni tabiiy tartibda qilish imkonini beradi. Birinchidan, biz `loadScript(script)`ni ishga tushiramiz va `.then` natija bilan nima qilishni yozamiz. | Biz `loadScript(script, callback)`ni chaqirishda `callback` funktsiyasiga ega bo'lishimiz kerak. Boshqacha qilib aytganda, `loadScript` chaqirilgunga _qadar_ natija bilan nima qilishni bilishimiz kerak. | +| Biz Promise'da `.then`ni xohlaganimizcha ko'p marta chaqirishimiz mumkin. Har safar biz yangi "muxlis", yangi obuna funktsiyasini "obuna ro'yxati"ga qo'shyapmiz. Bu haqida ko'proq keyingi bobda: [Promise Chaining](info:promise-chaining). | Faqat bitta callback bo'lishi mumkin. | -Shunday qilib promise-lar bizga yaxshiroq kod oqimi va moslashuvchanlik beradi. Lekin yana ko'p narsa bor. Buni keyingi boblarda ko'ramiz. \ No newline at end of file +Shunday qilib promise'lar bizga yaxshiroq kod oqimi va moslashuvchanlik beradi. Lekin yana ko'p narsa bor. Buni keyingi boblarda ko'ramiz. \ No newline at end of file diff --git a/1-js/11-async/03-promise-chaining/article.md b/1-js/11-async/03-promise-chaining/article.md index 87760d30d..3cf4a1a27 100644 --- a/1-js/11-async/03-promise-chaining/article.md +++ b/1-js/11-async/03-promise-chaining/article.md @@ -1,11 +1,10 @@ - -# Va'dalar zanjiri +# Promise Chaining bobida aytib o'tilgan muammoga qaytaylik: bizda birin-ketin bajariladigan asinxron vazifalar ketma-ketligi mavjud. Masalan, skriptlarni yuklash. Qanday qilib biz uni yaxshi kodlashimiz mumkin? -Buning uchun va'dalar bir nechta retseptlarni taqdim etadi. +Buning uchun promise'lar bir nechta yechimlarni taqdim etadi. -Ushbu bobda biz va'da zanjirini yoritamiz. +Ushbu bobda biz promise chaining'ni yoritamiz. Bu shunday ko'rinadi: @@ -32,41 +31,23 @@ new Promise(function(resolve, reject) { }); ``` -G'oya shundan iboratki, natija `.then` ishlovchilar zanjiri orqali o'tadi. +G'oya shundan iboratki, natija `.then` handlerlar zanjiri orqali o'tadi. Mana oqim: -1. Dastlabki va'da 1 soniyada hal qilinadi `(*)`, -2. Keyin `.then` ishlov beruvchisi `(**)` chaqiriladi. -3. Qaytgan qiymat keyingi `.then` ishlov beruvchiga `(***)` uzatiladi +1. Dastlabki promise 1 soniyada resolved bo'ladi `(*)`, +2. Keyin `.then` handler `(**)` chaqiriladi. +3. Qaytarilgan qiymat keyingi `.then` handlerga `(***)` uzatiladi 4. ...va hokazo. -Natijada ishlovchilar zanjiri bo'ylab uzatilganda biz `alert` chaqiruvlari ketma-ketligini ko'rishimiz mumkin: `1` -> `2` -> `4`. +Natija handlerlar zanjiri bo'ylab uzatilganda biz `alert` chaqiruvlari ketma-ketligini ko'rishimiz mumkin: `1` -> `2` -> `4`. ![](promise-then-chain.svg) -Hammasi ishlaydi, chunki `promise.then` degan chaqiriq va'dani qaytaradi, shunda biz keyingi `.then` ni chaqira olamiz. - -Qayta ishlovchi qiymatni qaytarganda, bu va'daning natijasi bo'ladi, shuning uchun keyingi `.then` u bilan chaqiriladi. - -Ushbu so'zlarni aniqroq qilish uchun, mana zanjirning boshlanishi: +Hammasi ishlaydi, chunki `promise.then` chaqiruvi promise qaytaradi, shunda biz keyingi `.then`ni chaqira olamiz. -```js run -new Promise(function(resolve, reject) { - - setTimeout(() => resolve(1), 1000); - -}).then(function(result) { +Handler qiymat qaytarganda, bu promise'ning natijasi bo'ladi, shuning uchun keyingi `.then` u bilan chaqiriladi. - alert(result); - return result * 2; // <-- (1) - -}) // <-- (2) -// .then… -``` - -`.then` tomonidan qaytarilgan qiymat va'da, shuning uchun biz `(2)` da yana bir `.then` qo'sha olamiz. Qiymat `(1)` ga qaytarilganda, bu va'da hal qilinadi, shuning uchun keyingi ishlov beruvchi qiymat bilan ishlaydi. - -**Klassik yangilar xatosi: texnik jihatdan biz bitta va'daga ko'p `.then` qo'sha olamiz. Bu zanjir emas.** +**Klassik yangi boshlovchilar xatosi: texnik jihatdan biz bitta promise'ga ko'plab `.then`larni qo'shishimiz mumkin. Bu chaining emas.** Masalan: ```js run @@ -90,21 +71,21 @@ promise.then(function(result) { }); ``` -Bu yerda qilgan narsamiz bu bitta va'daga bir nechta ishlovchilar qo'yganimiz. Ular natijani bir-biriga yetkazishmaydi, aksincha uni mustaqil ravishda qayta ishlashadi. +Bu yerda qilgan narsamiz - bitta promise'ga bir nechta handlerlar qo'shdik. Ular natijani bir-biriga uzatmaydi, aksincha uni mustaqil ravishda qayta ishlaydi. -Mana rasm (yuqoridagi zanjir bilan taqqoslang): +Mana rasm (yuqoridagi chain bilan taqqoslang): ![](promise-then-many.svg) -Barchasi `.then`, bitta va'da bo'yicha bir xil natijaga erishiladi - bu va'da natijasi. Shunday qilib, yuqoridagi kodda `alert` bir xil bo'ladi: `1`. +Bir xil promise'dagi barcha `.then`lar bir xil natijani oladi - o'sha promise'ning natijasini. Shunday qilib, yuqoridagi kodda barcha `alert`lar bir xil qiymatni ko'rsatadi: `1`. -Amalda biz kamdan-kam hollarda bitta va'da uchun bir nechta ishlov beruvchiga muhtojmiz. Zanjirlash juda tez-tez ishlatiladi. +Amalda biz kamdan-kam hollarda bitta promise uchun bir nechta handlerga muhtojmiz. Chaining juda ko'proq ishlatiladi. -## Va'dalarni qaytarish +## Promise'larni qaytarish -Odatda, `.then` ishlov beruvchisi tomonidan qaytarilgan qiymat darhol keyingi ishlov beruvchiga uzatiladi. Ammo istisno mavjud. +Odatda, `.then` handler tomonidan qaytarilgan qiymat darhol keyingi handlerga uzatiladi. Ammo istisno mavjud. -Agar qaytarib berilgan qiymat va'da bo'lsa, unda keyingi ijro to'xtaguncha to'xtatiladi. Shundan so'ng, ushbu va'daning natijasi keyingi `.then` ishlov beruvchiga beriladi. +Agar qaytarilgan qiymat promise bo'lsa, keyingi bajarilish u settled bo'lguncha to'xtatiladi. Shundan so'ng, o'sha promise'ning natijasi keyingi `.then` handlerga beriladi. Masalan: @@ -138,15 +119,15 @@ new Promise(function(resolve, reject) { }); ``` -Bu yerda birinchi `.then` `1` `(*)` satrida `new Promise(…)` ni qaytaradi. Bir soniyadan so'ng u hal bo'ladi va natija (`resolve` argumenti, bu yerda `result*2`) `(**)` satridagi ikkinchi `.then` ishlov beruvchiga uzatiladi. Bu `2` ni ko'rsatadi va xuddi shu narsani qiladi. +Bu yerda birinchi `.then` `1`ni ko'rsatadi va `(*)` satrida `new Promise(…)`ni qaytaradi. Bir soniyadan so'ng u resolved bo'ladi va natija (`resolve`ning argumenti, bu yerda `result * 2`) `(**)` satridagi ikkinchi `.then` handlerga uzatiladi. Bu handler `2`ni ko'rsatadi va xuddi shu narsani qiladi. Shunday qilib, chiqish yana 1 -> 2 -> 4 ni tashkil qiladi, ammo endi `alert` chaqiruvlari o'rtasida 1 soniya kechikish mavjud. -Va'dalarni qaytarish bizga asinxron harakatlar zanjirlarini yaratishga imkon beradi. +Promise'larni qaytarish bizga asinxron harakatlar zanjirlarini yaratishga imkon beradi. ## Misol: loadScript -Skriptlarni navbatma-navbat yuklash uchun ushbu funktsiyani `loadScript` bilan ishlatamiz: +Skriptlarni navbatma-navbat yuklash uchun oldingi bobdagi `loadScript` funktsiyasidan foydalanamiz: ```js run loadScript("/article/promise-chaining/one.js") @@ -165,32 +146,31 @@ loadScript("/article/promise-chaining/one.js") }); ``` -Ushbu kod o'q funktsiyalari bilan biroz qisqartirilishi mumkin: +Ushbu kod arrow funktsiyalar bilan biroz qisqartirilishi mumkin: ```js run loadScript("/article/promise-chaining/one.js") .then(script => loadScript("/article/promise-chaining/two.js")) .then(script => loadScript("/article/promise-chaining/three.js")) .then(script => { - // skriptlar yuklangan, biz u erda e'lon qilingan funktsiyalardan foydalanishimiz mumkin + // skriptlar yuklangan, biz ularda e'lon qilingan funktsiyalardan foydalanishimiz mumkin one(); two(); three(); }); ``` +Bu yerda har bir `loadScript` chaqiruvi promise qaytaradi va keyingi `.then` u resolved bo'lganda ishlaydi. Keyin u keyingi skriptni yuklashni boshlaydi. Shunday qilib, skriptlar birin-ketin yuklanadi. -Bu yerda har bir `loadScript` chaqiruvi va'da qaytaradi va keyingi `.then` hal bo'lganda ishlaydi. So'ng u keyingi skriptni yuklashni boshlaydi. Shunday qilib, skriptlar birin-ketin yuklanadi. +Biz zanjirga ko'proq asinxron harakatlarni qo'shishimiz mumkin. Iltimos, unutmangki, kod hali ham "tekis" bo'lib, u o'ngga emas, pastga qarab o'sadi. "Doom piramidasi"ning alomatlari yo'q. -Biz zanjirga ko'proq asinxron harakatlarni qo'shishimiz mumkin. Iltimos, unutmangki, kod hali ham "tekis" bo'lib, u o'ngga emas, pastga qarab o'sadi. "Halokat piramidasi" ning alomatlari yo'q. - -Iltimos, shuni e'tiborga olingki, texnik jihatdan biz har bir `loadScript` ga to'g'ridan-to'g'ri `.then` qo'sha olamiz: +Texnik jihatdan, biz har bir `loadScript`ga to'g'ridan-to'g'ri `.then` qo'shishimiz mumkin: ```js run loadScript("/article/promise-chaining/one.js").then(script1 => { loadScript("/article/promise-chaining/two.js").then(script2 => { loadScript("/article/promise-chaining/three.js").then(script3 => { - // bu funktsiya script1, script2 va script3 o'zgaruvchanlarga kirish huquqiga ega + // bu funktsiya script1, script2 va script3 o'zgaruvchilariga kirish huquqiga ega one(); two(); three(); @@ -199,19 +179,18 @@ loadScript("/article/promise-chaining/one.js").then(script1 => { }); ``` -Ushbu kod ham xuddi shunday: 3 ta skriptni ketma-ket yuklaydi. Ammo u "o'ng tomonga o'sadi". Shunday qilib, biz chaqiruvlarni qaytarish bilan bir xil muammolarga duch kelamiz. - -Va'dalardan foydalanishni boshlagan odamlar ba'zida zanjirlash haqida bilishmaydi, shuning uchun ular shunday yozadilar. Odatda, zanjirlash afzaldir. +Ushbu kod ham xuddi shunday ishlaydi: 3 ta skriptni ketma-ket yuklaydi. Ammo u "o'ng tomonga o'sadi". Shunday qilib, biz callback'lar bilan bir xil muammolarga duch kelamiz. -Ba'zan to'g'ridan-to'g'ri `.then` yozish yaxshi bo'ladi, chunki ichki funktsiya tashqi doiraga kirish huquqiga ega. Yuqoridagi misolda eng uyali qayta chaqirish `skript1`, `skript2`, `skript3` barcha o'zgaruvchanlariga kirish huquqiga ega. Ammo bu qoidadan ko'ra istisno. +Promise'lardan foydalanishni boshlagan odamlar ba'zan chaining haqida bilishmaydi, shuning uchun ular shunday yozadilar. Odatda, chaining afzaldir. +Ba'zan to'g'ridan-to'g'ri `.then` yozish yaxshi bo'ladi, chunki ichki funktsiya tashqi scope'ga kirish huquqiga ega. Yuqoridagi misolda eng ichki callback `script1`, `script2`, `script3` barcha o'zgaruvchilariga kirish huquqiga ega. Ammo bu qoidadan ko'ra istisno. -````smart header="Thenables" -Aniqroq qilib aytganda, `.then` tasodifiy "thenable" obyektni qaytarishi mumkin va unga va'da kabi munosabatda bo'lishadi. +````smart header="Thenable'lar" +Aniqroq qilib aytganda, handler tasodifiy "thenable" obyektni qaytarishi mumkin va unga promise kabi munosabatda bo'linadi. -"Thenable" obyekt `.then` usuli bo'lgan har qanday obyekt. +"Thenable" obyekt - `.then` metodi bo'lgan har qanday obyekt. -Ushbu g'oya shundan iboratki, uchinchi tomon kutubxonalari o'zlariga tegishli "va'dalarga mos" obyektlarni amalga oshirishi mumkin. Ular kengaytirilgan usullar to'plamiga ega bo'lishi mumkin, shuningdek, mahalliy va'dalarga mos kelishi mumkin, chunki ular `.then` ni amalga oshiradilar. +Ushbu g'oya shundan iboratki, uchinchi tomon kutubxonalar o'zlariga tegishli "promise-compatible" obyektlarni amalga oshirishi mumkin. Ular kengaytirilgan metodlar to'plamiga ega bo'lishi mumkin, shuningdek, native promise'lar bilan mos kelishi mumkin, chunki ular `.then`ni implement qiladi. Thenable obyektga misol: @@ -236,67 +215,66 @@ new Promise(resolve => resolve(1)) .then(alert); // 1000ms dan keyin 2 ni ko'rsatadi ``` -JavaScript `.then` `(*)` satridagi `.then` ishlov beruvchisi tomonidan qaytarilgan obyektni tekshiradi: agar u `then` deb nomlanadigan usulga ega bo'lsa, u holda bu tabiiy funktsiyalarni taqdim etadigan ushbu usulni `resolve`, `reject` argument sifatida chaqiradi (ijrochiga o'xshash) va ulardan biri chaqirilguncha kutadi. Yuqoridagi misolda `resolve(2)` 1 soniyadan so'ng chaqiriladi `(**)`. Keyin natija zanjirning pastki qismiga uzatiladi. +JavaScript `(*)` satrida `.then` handler tomonidan qaytarilgan obyektni tekshiradi: agar unda `then` deb nomlangan method bo'lsa, u holda bu method `resolve`, `reject` ni argument sifatida qabul qiladigan native funktsiyalar bilan chaqiriladi (executor'ga o'xshash) va ulardan biri chaqirilguncha kutadi. Yuqoridagi misolda `resolve(2)` 1 soniyadan so'ng `(**)` da chaqiriladi. Keyin natija zanjirning pastki qismiga uzatiladi. -Ushbu xususiyat `Promise` dan meros olmasdan, moslashtirilgan moslamalarni va'da zanjirlari bilan birlashtirishga imkon beradi. +Ushbu xususiyat `Promise`dan meros olmasdan, custom obyektlarni promise chainlariga integratsiya qilishga imkon beradi. ```` - ## Kattaroq misol: fetch -Frontend dasturlash va'dalari ko'pincha tarmoq so'rovlari uchun ishlatiladi. Keling, buning kengaytirilgan namunasini ko'rib chiqaylik. +Frontend dasturlashda promise'lar ko'pincha tarmoq so'rovlari uchun ishlatiladi. Keling, buning kengaytirilgan namunasini ko'rib chiqaylik. -Uzoq serverdan foydalanuvchi haqidagi ma'lumotlarni yuklash uchun [fetch](mdn:api/WindowOrWorkerGlobalScope/fetch) usulidan foydalanamiz. Usul juda murakkab, ko'plab ixtiyoriy parametrlarga ega, ammo asosiy foydalanish juda oddiy: +Uzoq serverdan foydalanuvchi haqidagi ma'lumotlarni yuklash uchun [fetch](mdn:api/WindowOrWorkerGlobalScope/fetch) metodidan foydalanamiz. Method juda ko'p ixtiyoriy parametrlarga ega, ammo asosiy foydalanish juda oddiy: ```js let promise = fetch(url); ``` -Bu `url` ga tarmoq so'rovini yuboradi va va'da qaytaradi. Masofaviy server sarlavhalar bilan javob berganida, va *to'liq javob yuklab olinmasdan oldin* va'da `response` obyekti bilan hal qilinadi. +Bu `url`ga tarmoq so'rovini yuboradi va promise qaytaradi. Remote server headerlar bilan javob berganida, *to'liq javob yuklab olinmasdan oldin* promise `response` obyekti bilan resolved bo'ladi. -To'liq javobni o'qish uchun biz `response.text()` usulini chaqirishimiz kerak: bu to'liq matnni uzoq serverdan yuklab olganda va natijada ushbu matn bilan hal qilinadigan va'dani qaytaradi. +To'liq javobni o'qish uchun biz `response.text()` metodini chaqirishimiz kerak: u to'liq matnni remote serverdan yuklab olganda resolved bo'ladigan promise qaytaradi. -Quyidagi kod `user.json` ga so'rov yuboradi va uning matnini serverdan yuklaydi: +Quyidagi kod `user.json`ga so'rov yuboradi va uning matnini serverdan yuklaydi: ```js run fetch('/article/promise-chaining/user.json') - // .then masofaviy server javob berganida quyida ishlaydi + // .then quyida remote server javob berganida ishlaydi .then(function(response) { - // response.text() javobning to'liq matni bilan hal qilinadigan yangi va'dani qaytaradi - // uni yuklab olishni tugatgandan so'ng + // response.text() javobning to'liq matni bilan resolved bo'ladigan yangi promise qaytaradi + // yuklab olishni tugatgandan so'ng return response.text(); }) .then(function(text) { - // ...va bu erda masofaviy faylning mazmuni - alert(text); // {"name": "iliakan", isAdmin: true} + // ...va bu erda remote faylning tarkibi + alert(text); // {"name": "iliakan", "isAdmin": true} }); ``` -Masofaviy ma'lumotlarni o'qiydigan va ularni JSON sifatida tahlil qiladigan `response.json()` usuli ham mavjud. Bizning holatda bu yanada qulayroq, shuning uchun unga o'taylik. +`fetch` tomonidan qaytarilgan `response` obyekti remote ma'lumotlarni JSON sifatida o'qiydigan va parse qiladigan `response.json()` metodini ham o'z ichiga oladi. Bizning holatda bu yanada qulayroq, shuning uchun unga o'taylik. -Qisqartirish uchun biz o'q funktsiyalaridan foydalanamiz: +Qisqartirish uchun arrow funktsiyalardan foydalanamiz: ```js run -// yuqoridagi kabi, ammo response.json() masofaviy tarkibni JSON sifatida ajratadi +// yuqoridagi kabi, ammo response.json() remote tarkibni JSON sifatida parse qiladi fetch('/article/promise-chaining/user.json') .then(response => response.json()) - .then(user => alert(user.name)); // iliakan, got user name + .then(user => alert(user.name)); // iliakan, foydalanuvchi ismini oldik ``` Endi yuklangan foydalanuvchi bilan nimadir qilaylik. -Masalan, github-ga yana bir so'rov yuborishimiz, foydalanuvchi profilini yuklashimiz va avatarni ko'rsatishimiz mumkin: +Masalan, GitHub'ga yana bir so'rov yuborishimiz, foydalanuvchi profilini yuklashimiz va avatarni ko'rsatishimiz mumkin: ```js run -// User.json uchun so'rov yuboring +// user.json uchun so'rov yuboring fetch('/article/promise-chaining/user.json') - // Json sifatida yuklang + // json sifatida yuklang .then(response => response.json()) - // Github-ga so'rov yuboring + // GitHub'ga so'rov yuboring .then(user => fetch(`https://api.github.com/users/${user.name}`)) - // Javobni json sifatida yuklang + // javobni json sifatida yuklang .then(response => response.json()) - // Avatar rasmini ko'rsating (githubUser.avatar_url) 3 soniya davomida (balki uni jonlantirish mumkin) + // avatar rasmini ko'rsating (githubUser.avatar_url) 3 soniya davomida (balki uni animate qilish mumkin) .then(githubUser => { let img = document.createElement('img'); img.src = githubUser.avatar_url; @@ -307,11 +285,11 @@ fetch('/article/promise-chaining/user.json') }); ``` -Kod ishlaydi, tafsilotlar haqidagi sharhlarni ko'ring, lekin u o'zi tavsiflovchi bo'lishi kerak. Garchi unda potentsial muammo mavjud bo'lsa ham, va'da ishlatishni boshlaganlar uchun odatiy xato. +Kod ishlaydi, tafsilotlar haqidagi izohlarni ko'ring, lekin u o'zi-o'zidan tushunarli bo'lishi kerak. Garchi unda potentsial muammo mavjud bo'lsa ham - promise'larni ishlatishni boshlaganlar uchun odatiy xato. -`(*)` satriga qarang: avatar ko'rsatilgandan so'ng va olib tashlanganidan *keyin* qanday qilib biron bir narsa qilishimiz mumkin? Masalan, biz ushbu foydalanuvchini yoki boshqa biron bir narsani tahrirlash uchun shaklni ko'rsatmoqchimiz. Hozircha iloj yo'q. +`(*)` satriga qarang: avatar ko'rsatilgandan va olib tashlanganidan *keyin* qanday qilib biron narsa qilishimiz mumkin? Masalan, biz ushbu foydalanuvchini tahrirlash uchun forma ko'rsatmoqchimiz yoki boshqa biron narsa. Hozircha iloj yo'q. -Zanjirni uzaytiradigan qilish uchun, biz avatarni ko'rsatishni tugatgandan so'ng hal qiladigan va'dani qaytarishimiz kerak. +Zanjirni davom ettirish uchun, biz avatar ko'rsatilishini tugatgandan so'ng resolved bo'ladigan promise qaytarishimiz kerak. Shunga o'xshash: @@ -335,17 +313,15 @@ fetch('/article/promise-chaining/user.json') */!* }, 3000); })) - // 3 soniyadan keyin namoyish etadi - .then(githubUser => alert(`Namoyishni tugadi ${githubUser.name}`)); + // 3 soniyadan keyin ishlaydi + .then(githubUser => alert(`${githubUser.name} uchun ko'rsatish tugadi`)); ``` -Endi `setTimeout` `img.remove()` ni ishga tushirgandan so'ng, `resolve(githubUser)` ni chaqiradi, shu bilan boshqaruvni zanjirdagi keyingi `.then` ga uzatadi va foydalanuvchi ma'lumotlarini uzatadi. - -Qoida tariqasida, asinxron harakat har doim va'dani qaytarishi kerak. +Endi `setTimeout` `img.remove()`ni ishga tushirgandan so'ng, `resolve(githubUser)`ni chaqiradi, shu bilan boshqaruvni zanjirdagi keyingi `.then`ga uzatadi va foydalanuvchi ma'lumotlarini uzatadi. -Bu undan keyin harakatlarni rejalashtirishga imkon beradi. Agar biz hozirda zanjirni kengaytirishni rejalashtirmagan bo'lsak ham, keyinroq kerak bo'lishi mumkin. +Qoida tariqasida, asinxron harakat har doim promise qaytarishi kerak. Bu undan keyin harakatlarni rejalashtirishga imkon beradi; hozirda zanjirni kengaytirishni rejalashtirmasak ham, keyinroq kerak bo'lishi mumkin. -Va nihoyat, biz kodni qayta ishlatiladigan funktsiyalarga bo'lishimiz mumkin: +Va nihoyat, biz kodni qayta foydalaniladigan funktsiyalarga bo'lishimiz mumkin: ```js run function loadJson(url) { @@ -376,14 +352,14 @@ function showAvatar(githubUser) { loadJson('/article/promise-chaining/user.json') .then(user => loadGithubUser(user.name)) .then(showAvatar) - .then(githubUser => alert(`Namoyish tugadi ${githubUser.name}`)); + .then(githubUser => alert(`${githubUser.name} uchun ko'rsatish tugadi`)); // ... ``` ## Xulosa -Agar `.then` (yoki `catch/finally` ahamiyati yo'q) ishlov beruvchisi va'da bersa, qolgan zanjir o'rnashguncha kutadi. Qachonki u bajarilsa, uning natijasi (yoki xatosi) yana uzatiladi. +Agar `.then` (yoki `catch/finally`, farqi yo'q) handler promise qaytarsa, qolgan zanjir u settled bo'lguncha kutadi. U settled bo'lganda, uning natijasi (yoki xatosi) keyingi handlerga uzatiladi. Mana to'liq rasm: -![](promise-handler-variants.svg) +![](promise-handler-variants.svg) \ No newline at end of file diff --git a/1-js/11-async/04-promise-error-handling/article.md b/1-js/11-async/04-promise-error-handling/article.md index 6ead2ed16..0801f3a41 100644 --- a/1-js/11-async/04-promise-error-handling/article.md +++ b/1-js/11-async/04-promise-error-handling/article.md @@ -1,8 +1,8 @@ -# Va'dalar bilan ishlashda xato +# Promiselar bilan ishlashda xato -Asinxron harakatlar ba'zan muvaffaqiyatsiz bo'lishi mumkin: xato bo'lsa, tegishli va'da rad etiladi. Masalan, masofaviy server mavjud bo'lmasa, `fetch` bajarilmaydi. Xatolarni (rad etishlarni) boshqarish uchun `.catch` dan foydalanishimiz mumkin. +Asinxron harakatlar ba'zan muvaffaqiyatsiz bo'lishi mumkin: xato bo'lsa, tegishli Promise rad etiladi. Masalan, masofaviy server mavjud bo'lmasa, `fetch` bajarilmaydi. Xatolarni (rad etishlarni) boshqarish uchun `.catch` dan foydalanishimiz mumkin. -Va'da zanjiri bu jihatdan juda yaxshi. Va'da rad etilganda, boshqaruv zanjir bo'ylab eng yaqin rad etuvchiga sakraydi. Bu amalda juda qulay. +Promise zanjiri bu jihatdan juda yaxshi. Promise rad etilganda, boshqaruv zanjir bo'ylab eng yaqin rad etuvchiga sakraydi. Bu amalda juda qulay. Masalan, URL ostidagi kodda xato (bunday server yo'q) va `.catch` xatoni boshqaradi: @@ -47,11 +47,11 @@ fetch('/article/promise-chaining/user.json') */!* ``` -Odatda `.catch` umuman bajarilmaydi, chunki xatolar yo'q. Ammo agar yuqoridagi va'dalardan birortasi rad etsa (tarmoq muammosi yoki yaroqsiz json yoki boshqa narsalar), u buni bajaradi. +Odatda `.catch` umuman bajarilmaydi, chunki xatolar yo'q. Ammo agar yuqoridagi promiselardan birortasi rad etsa (tarmoq muammosi yoki yaroqsiz json yoki boshqa narsalar), u buni bajaradi. ## Yashirin try..catch -Va'da ijrochisi va va'da ishlovchilarining kodi atrofida "ko'rinmas `try..catch`" bor. Agar xato yuz bersa, u ushlanib qoladi va rad etish sifatida qabul qilinadi. +Promize ijrochisi va promise ishlovchilarining kodi atrofida "ko'rinmas `try..catch`" bor. Agar xato yuz bersa, u ushlanib qoladi va rad etish sifatida qabul qilinadi. Masalan, ushbu kod: @@ -75,7 +75,7 @@ new Promise((resolve, reject) => { Ijrochining atrofidagi "ko'rinmas `try..catch`" avtomatik ravishda xatoni ushlaydi va uni rad etish sifatida qabul qiladi. -Bu nafaqat ijrochida, balki uning ishlovchilarida ham bo'ladi. Agar biz `.then` ishlov beruvchisiga `throw` qo'ysak, bu rad etilgan va'dani anglatadi, shuning uchun boshqaruv eng yaqin xato ishlov beruvchiga sakraydi. +Bu nafaqat ijrochida, balki uning ishlovchilarida ham bo'ladi. Agar biz `.then` ishlov beruvchisiga `throw` qo'ysak, bu rad etilgan promiseni anglatadi, shuning uchun boshqaruv eng yaqin xato ishlov beruvchiga sakraydi. Mana bir misol: @@ -84,7 +84,7 @@ new Promise((resolve, reject) => { resolve("ok"); }).then((result) => { *!* - throw new Error("Whoops!"); // va'dani rad etadi + throw new Error("Whoops!"); // promiseni rad etadi */!* }).catch(alert); // Error: Whoops! ``` @@ -107,7 +107,7 @@ Yakuniy `.catch` nafaqat aniq rad etishlarni, balki yuqoridagi ishlovchilarda va Biz allaqachon payqaganimizdek, `.catch` o'zini `try..catch` kabi tutadi. Biz istagancha `.then` ishlovchilarga ega bo'lishimiz mumkin, so'ngra ularning barchasida xatolarni boshqarish uchun oxirida bitta `.catch` dan foydalanishimiz mumkin. -Muntazam ravishda `try..catch` da biz xatoni tahlil qilamiz va agar uni uddalay olmasak, uni qayta tiklaymiz. Xuddi shu narsa va'dalar uchun ham mumkin. +Muntazam ravishda `try..catch` da biz xatoni tahlil qilamiz va agar uni uddalay olmasak, uni qayta tiklaymiz. Xuddi shu narsa promiselar uchun ham mumkin. Agar biz `.catch` ichiga `throw` qo'ysak, boshqaruv keyingi eng yaqin xato ishlovchilariga o'tadi. Agar biz xatoga yo'l qo'ysak va odatdagidek tugatsak, u eng yaqin muvaffaqiyatli `.then` da davom etadi. @@ -164,7 +164,7 @@ Quyidagi bo'limda biz qayta ko'rib chiqishning amaliy namunasini ko'rib chiqamiz Keling, foydalanuvchini yuklash misoli uchun xatolar bilan ishlashni yaxshilaymiz. -[fetch](mdn:api/WindowOrWorkerGlobalScope/fetch) tomonidan qaytarilgan va'da so'rov yuborish imkonsiz bo'lganda rad etadi. Masalan, masofaviy server mavjud emas yoki URL manzili noto'g'ri. Ammo agar masofaviy server 404 yoki hatto 500 xatosi bilan javob bersa, u to'g'ri javob deb hisoblanadi. +[fetch](mdn:api/WindowOrWorkerGlobalScope/fetch) tomonidan qaytarilgan promise so'rov yuborish imkonsiz bo'lganda rad etadi. Masalan, masofaviy server mavjud emas yoki URL manzili noto'g'ri. Ammo agar masofaviy server 404 yoki hatto 500 xatosi bilan javob bersa, u to'g'ri javob deb hisoblanadi. Agar server JSON-ga tegishli bo'lmagan sahifani `(*)` satrida 500 xatosi bilan qaytarsa nima bo'ladi? Agar bunday foydalanuvchi bo'lmasa va github 404 xatosi bo'lgan sahifani `(**)` ga qaytarsa nima bo'ladi? @@ -256,11 +256,11 @@ Yoki biz zanjirning oxiriga xato ishlov beruvchini qo'shishni unutishimiz mumkin new Promise(function () { noSuchFunction(); // Bu erda xato (bunday funktsiya yo'q) }).then(() => { - // nol yoki ko'plab va'da beruvchi ishlovchilar + // nol yoki ko'plab promise beruvchi ishlovchilar }); // oxirida .catch siz! ``` -Xato bo'lsa, va'da holati "rad etilgan" bo'lib qoladi va ijro eng yaqin rad etuvchiga o'tishi kerak. Ammo yuqoridagi misollarda bunday ishlov beruvchi yo'q. Shunday qilib, xato "tiqilib qoladi". +Xato bo'lsa, promise holati "rad etilgan" bo'lib qoladi va ijro eng yaqin rad etuvchiga o'tishi kerak. Ammo yuqoridagi misollarda bunday ishlov beruvchi yo'q. Shunday qilib, xato "tiqilib qoladi". Amalda, xuddi odatdagi ishlov berilmagan xatolar singari, bu ham biron bir narsa noto'g'ri ketganligini anglatadi, ehtimol skript o'lgan. @@ -272,7 +272,7 @@ Brauzerda biz `unhandledrejection` hodisasi yordamida bunday xatolarga yo'l qo'y *!* window.addEventListener('unhandledrejection', function(event) { // hodisa obyekti ikkita maxsus xususiyatga ega: - alert(event.promise); // [object Promise] - xatoni keltirib chiqargan va'da + alert(event.promise); // [object Promise] - xatoni keltirib chiqargan promise alert(event.reason); // Error: Whoops! - ishlov berilmagan xato obyekti }); */!* @@ -292,7 +292,7 @@ Node.js kabi brauzerdan tashqari muhitda ishlov berilmagan xatolarni kuzatib bor ## Xulosa -- `.catch` tutqichlari har qanday rad etishni va'da qiladi: `reject()` chaqiruvi yoki ishlov beruvchiga xato tashlanadi. +- `.catch` tutqichlari har qanday rad etishni tutib qoladi: `reject()` chaqiruvi yoki ishlov beruvchiga xato tashlanadi. - Biz xatolarni ko'rib chiqishni va ularni qanday boshqarishni bilishni xohlagan joylarga `.catch` ni aniq joylashtirishimiz kerak. Ishlovchi xatolarni tahlil qilishi kerak (maxsus xato klasslari yordam beradi) va noma'lumlarini qayta tiklashi kerak. - Xatolarni qanday hal qilishni bilmasak, `.catch` dan foydalanmaslik odatiy holdir (barcha xatolar tiklanmaydi). - Qanday bo'lmasin, biz ishlov berilmagan xatolarni kuzatib borish va ular haqida foydalanuvchini (va ehtimol bizning serverimiz) xabardor qilish uchun `unhandledrejection` voqea ishlovchisiga ega bo'lishimiz kerak (brauzerlar va boshqa muhitlar uchun analoglar), shunda bizning dasturimiz hech qachon "shunchaki o'lmaydi" . @@ -333,6 +333,6 @@ demoGithubUser(); Bu yerda `(1)` satrida biz hujjatni xiralashtirish orqali yuklanishni ko'rsatamiz. Usul muhim emas, buning o'rniga har qanday ko'rsatkichni ishlatishi mumkin. -Va'da bajarilgandan so'ng, u muvaffaqiyatli fetch yoki xato bo'ladimi, `finally` `(2)` satrida boshlanadi va ko'rsatkichni to'xtatadi. +Promise bajarilgandan so'ng, u muvaffaqiyatli fetch yoki xato bo'ladimi, `finally` `(2)` satrida boshlanadi va ko'rsatkichni to'xtatadi. -`finally` dan nol-tanaffus va'dasini qaytarish bilan `(*)` brauzerning kichik hiyla-nayranglari mavjud. Buning sababi shundaki, ba'zi brauzerlar (masalan, Chrome) hujjatdagi o'zgarishlarni bo'yash uchun tashqarida va'da beruvchilarga "biroz vaqt" kerak. Shunday qilib, zanjirga o'tmasdan oldin ko'rsatkich vizual ravishda to'xtatilishini ta'minlaydi. +`finally` dan nol-tanaffus promiseni qaytarish bilan `(*)` brauzerning kichik hiyla-nayranglari mavjud. Buning sababi shundaki, ba'zi brauzerlar (masalan, Chrome) hujjatdagi o'zgarishlarni bo'yash uchun tashqarida promise qiymatlariga "biroz vaqt" kerak. Shunday qilib, zanjirga o'tmasdan oldin ko'rsatkich vizual ravishda to'xtatilishini ta'minlaydi. diff --git a/2-ui/index.md b/2-ui/index.md index 75f563fcf..1f296479e 100644 --- a/2-ui/index.md +++ b/2-ui/index.md @@ -1,3 +1,3 @@ -# Bauzer: Hujjatlar, Voqealar, Interfeyslar +# Brauzer: Hujjatlar, Voqealar, Interfeyslar Brauzer sahifasini qanday boshqarishni o'rganish: elementlarni qo'shish, ularning o'lchamlari va holatini boshqarish, dinamik ravishda interfeyslarni yaratish va tashrif buyuruvchi bilan o'zaro aloqada bo'lish.