JavaScript-да promise hell муаммоси
Сиз биласизки, промислар callback hell муаммосини ҳал қилиш учун яратилган эди. Аммо, вақт ўтиши билан маълум бўлдики, промислар ҳам мураккаб кодни вужудга келтириши мумкин. Бу муаммо ўхшашлик асосида promise hell деб номланди.
Келинг, бу муаммони код мисолларида кўриб чиқайлик.
Фарз қилайлик, бизда getSmth функцияси бор,
у параметр олади ва шу параметрга боғлиқ холда натижа қайтаради:
function getSmth(num) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(num * num), 1000)
});
}
Бу ҳолда биз бирор фойдали амални (масалан, сервердан маълумот олишни) таклид қиламиз. Таклид қилиш учун биз оддий равишда параметр сифатида сон берамиз ва бир сониядан сўнг шу соннинг квадратини қайтарамиз.
Энди бизнинг getSmth функциямиздан бошқа функция ичида фойдаланайлик:
function func() {
getSmth(2).then(res => {
console.log(res); // 4 ни чиқаради
});
}
func();
Биринчи муаммо
Бир-бирини кейинан келган кўпгина then конструкциялари
кодни тушунишни кийинлаштиради:
function func(){
getSmth(2).then(res1 => {
// бирор иш бажарамиз
}).then(res2 => {
// бирор иш бажарамиз
}).then(res3 => {
// бирор иш бажарамиз
}).then(res4 => {
// бирор иш бажарамиз
}).then(res5 => {
// бирор иш бажарамиз
}).then(res6 => {
// бирор иш бажарамиз
});
}
func();
Иккинчи муаммо
Бошқа муаммо ҳам мавжуд. Фарз қилайлик, энди биз функциямиздан икки марта фойдаланмоқчимиз, сўнг натижаларни йиғмоқчимиз. Натижада бизга мана бу код хосил бўлади:
function func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
console.log(res1 + res2); // 13 ни чиқаради
});
});
}
func();
Ҳозирганоқ callback hell-ни эслата бошлади, шундай эмасми? Яна бир функция чақириғини қўшайлик - код янда ҳам ёмонроқ бўлади:
function func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
getSmth(4).then(res3 => {
console.log(res1 + res2 + res3);
});
});
});
}
func();
Албатта, Promise.all-дан фойдаланиш мумкин:
function func() {
Promise.all([getSmth(2), getSmth(3), getSmth(4)]).then(res => {
console.log(res[0] + res[1] + res[2]);
});
}
func();
Бирок, биз худди шу натижага эришдикми? Йўқ! Биринчи ҳолда ҳар бир янги функция олдинги промиснинг тугашини кутadi, иккинчи ҳолда эса - барча промислар бир вақтда бажарилади. Бу фарқ биз кейинги функцияга олдингини чақиришни ўтказмоқчи бўлганимизда мухим аҳамият касб этади:
function func() {
getSmth(2).then(res1 => {
getSmth(res1).then(res2 => {
getSmth(res2).then(res3 => {
console.log(res3);
});
});
});
}
func();