Promise zanjiri
Ko'pincha bir nechta asinxron ishni ketma-ket bajarishimiz kerak bo'ladi: masalan, ma'lumot yuklab, uni qayta ishlab, so'ng saqlash. Promise buni zanjir (chaining) orqali chiroyli hal qiladi โ callback jahannamisiz, tekis kod bilan. Ushbu darsda Promise zanjirini o'rganamiz.
Zanjirning asosiy g'oyasi
Promise zanjiri quyidagi g'oyaga asoslanadi: promise.then(...) chaqiruvi yangi Promise qaytaradi. Demak, uning ustiga yana .then ulashimiz mumkin. Va yana. Va yana โ natijada zanjir hosil bo'ladi:
new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(1);
}, 1000);
})
.then(function (result) {
console.log(result); // 1
return result * 2;
})
.then(function (result) {
console.log(result); // 2
return result * 2;
})
.then(function (result) {
console.log(result); // 4
return result * 2;
});
// Konsolda: 1, keyin 2, keyin 4
G'oya shunda: har bir .thendan return qilingan qiymat keyingi .thenga uzatiladi. Shunday qilib, natija zanjir bo'ylab bosqichma-bosqich "oqib" boradi.
.then har doim yangi Promise qaytaradi. Uning callback'idan qaytgan qiymat esa shu yangi Promise'ning natijasiga aylanadi.Xato: zanjir emas, ko'p mustaqil .then
Yangi boshlovchilar ko'p qiladigan xato โ bitta Promise'ga bir nechta .thenni alohida ulash va uni zanjir deb o'ylash. Bu butunlay boshqa narsa:
const promise = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(1);
}, 1000);
});
// BU ZANJIR EMAS! Uch mustaqil .then bitta promise'ga ulangan
promise.then(function (result) {
console.log(result); // 1
return result * 2;
});
promise.then(function (result) {
console.log(result); // 1 (2 emas!)
return result * 2;
});
promise.then(function (result) {
console.log(result); // 1 (4 emas!)
});
// Konsolda: 1, 1, 1
.then ham bitta va o'sha Promise'ni mustaqil qayta ishlaydi, natijani bir-biriga uzatmaydi. Shuning uchun uchalasi ham 1 chiqaradi. Zanjir bo'lishi uchun .thenlar bir-birining natijasiga ulanishi kerak (nuqta orqali ketma-ket)..then ichida Promise qaytarish
Zanjirning eng kuchli jihati: .thenning callback'idan oddiy qiymat emas, balki yangi Promise qaytarish mumkin. Bunday holda zanjir shu yangi Promise hal bo'lguncha kutadi, so'ng uning natijasi bilan davom etadi.
new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(1);
}, 1000);
})
.then(function (result) {
console.log(result); // 1
// Oddiy qiymat emas, YANGI Promise qaytaramiz:
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(result * 2);
}, 1000);
});
})
.then(function (result) {
// Bu .then yuqoridagi yangi Promise hal bo'lgach ishlaydi
console.log(result); // 2
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(result * 2);
}, 1000);
});
})
.then(function (result) {
console.log(result); // 4
});
// Har bosqich 1 sekund kutadi: 1 (1s), 2 (2s), 4 (3s)
Aynan shu imkoniyat โ .thendan Promise qaytarish โ bizga ketma-ket asinxron ishlarni tekis yozishga imkon beradi. Har bir bosqich oldingisi tugagach boshlanadi.
.thendan Promise qaytarsangiz, JavaScript uni "kutib" beradi. Agar oddiy qiymat qaytarsangiz โ u darhol keyingi bosqichga uzatiladi. Ikkala holat ham bir xil sintaksis bilan ishlaydi.Amaliy misol: ketma-ket skript yuklash
Oldingi darslarda callback bilan uch skriptni ketma-ket yuklaganimizni eslang โ piramida hosil bo'lgandi. Promise bilan ayni ishni tekis yozamiz. loadScript endi Promise qaytaradi deb faraz qilaylik:
// loadScript(src) endi Promise qaytaradi deb faraz qilaylik
loadScript("1.js")
.then(function () {
return loadScript("2.js");
})
.then(function () {
return loadScript("3.js");
})
.then(function () {
console.log("Uchala skript ham ketma-ket yuklandi!");
});
Callback varianti bilan solishtiring: u yerda kod o'ngga qarab chuqurlashardi (piramida). Bu yerda esa zanjir tekis โ har bir .then bir xil chuqurlikda, pastga qarab o'qiladi. Bu Promise zanjirining asosiy yutug'i.
Zanjirda qiymatlarni uzatishni tushunish
Sodda sinxron misol bilan "qiymat zanjir bo'ylab uzatiladi" g'oyasini mustahkamlaymiz. Bu yerda darhol hal bo'lgan Promise ishlatilgan, shuning uchun natijalar konsolda ko'rinadi:
Promise.resolve(5) โ darhol 5 qiymati bilan bajarilgan Promise yaratadi. So'ng har bosqich oldingisining natijasini oladi, o'zgartiradi va keyingisiga uzatadi: 5 → 15 → 30.
Promise.resolve(value) โ tayyor (fulfilled) Promise yaratishning qisqa usuli. Zanjirni boshlash yoki qiymatni Promise ichiga "o'rash" uchun qulay.Xulosa
.thenhar doim yangi Promise qaytaradi โ shuning uchun zanjirlash mumkin;.thendanreturnqilingan qiymat keyingi.thenga uzatiladi;.thendan Promise qaytarilsa, zanjir uni kutadi va natijasi bilan davom etadi;- Bir Promise'ga alohida bir necha
.thenulash โ bu zanjir emas, mustaqil qayta ishlashdir; - Promise zanjiri tekis bo'ladi โ callback piramidasi o'rniga yuqoridan pastga o'qiladi.