JavaScript-də promise hell problemi
Artıq bilirsiniz ki, promislər callback hell problemini həll etmək üçün yaradılmışdı. Lakin, zaman keçdikcə məlum oldu ki, promislər də mürəkkəb kod yarada bilər. Bu problem bənzətmə yolu ilə promise hell adlandırıldı.
Gəlin bu problemi kod nümunələri üzərində nəzərdən keçirək. Tutaq ki, bizim parametr alan və həmin parametrdən asılı olaraq nəticə qaytaran getSmth funksiyamız var:
function getSmth(num) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(num * num), 1000)
});
}
Bu halda biz hansısa faydalı əməliyyatı (məsələn, serverdən məlumat almağı) təqlid edirik. Təqlid etmək üçün biz sadəcə parametr kimi ədəd ötürürük və bir saniyədən sonra həmin ədədin kvadratını qaytarırıq.
Gəlin indi bizim getSmth funksiyamızdan başqa bir funksiya daxilində istifadə edək:
function func() {
getSmth(2).then(res => {
console.log(res); // 4 çap edəcək
});
}
func();
Birinci problem
Bir-birinin ardınca gələn çoxlu then konstruksiyaları kodun başa düşülməsini çətinləşdirir:
function func(){
getSmth(2).then(res1 => {
// bir şey edirik
}).then(res2 => {
// bir şey edirik
}).then(res3 => {
// bir şey edirik
}).then(res4 => {
// bir şey edirik
}).then(res5 => {
// bir şey edirik
}).then(res6 => {
// bir şey edirik
});
}
func();
Ikinci problem
Başqa bir problem də var. Tutaq ki, indi biz funksiyamızdan iki dəfə istifadə etmək, sonra isə nəticələri toplamaq istəyirik. Nəticədə biz belə bir kod alırıq:
function func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
console.log(res1 + res2); // 13 çap edəcək
});
});
}
func();
Artıq callback hell-i xatırladır, elə deyilmi? Bir funksiya çağırışı daha əlavə edək - kod daha da pisləşəcək:
function func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
getSmth(4).then(res3 => {
console.log(res1 + res2 + res3);
});
});
});
}
func();
Əlbəttə ki, Promise.all-dən istifadə edə bilərik:
function func() {
Promise.all([getSmth(2), getSmth(3), getSmth(4)]).then(res => {
console.log(res[0] + res[1] + res[2]);
});
}
func();
Lakin, biz eyni şeyi aldıqmi? Xeyr! Birinci halda hər yeni funksiya əvvəlki promisin bitməsini gözləyir, ikinci halda isə - bütün promislər eyni zamanda yerinə yetirilir. Bu fərq o zaman əhəmiyyətli olacaq ki, biz növbəti funksiyaya əvvəlkinin çağırışını ötürmək istəyək:
function func() {
getSmth(2).then(res1 => {
getSmth(res1).then(res2 => {
getSmth(res2).then(res3 => {
console.log(res3);
});
});
});
}
func();