Problem promise hell-a u JavaScript-u
Već znate da su promisi stvoreni da reše problem callback hell-a. Međutim, vremenom se pokazalo da promisi takođe mogu stvoriti složen kod. Ovaj problem je po analogiji nazvan promise hell.
Hajde da razmotrimo ovaj problem na primerima
koda. Pretpostavimo da imamo funkciju getSmth,
koja prima parametar i vraća rezultat
zavisno od tog parametra:
function getSmth(num) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(num * num), 1000)
});
}
U ovom slučaju imitirajmo neku korisnu operaciju (na primer, preuzimanje podataka sa servera). Kao imitaciju, jednostavno prosledimo broj kao parametar i za sekundu vratimo kvadrat tog broja.
Sada hajde da iskoristimo našu funkciju
getSmth unutar druge funkcije:
function func() {
getSmth(2).then(res => {
console.log(res); // ispisaće 4
});
}
func();
Prvi problem
Brojne konstrukcije then koje se
jedna za drugom javljaju, otežavaju razumevanje koda:
function func(){
getSmth(2).then(res1 => {
// radimo nešto
}).then(res2 => {
// radimo nešto
}).then(res3 => {
// radimo nešto
}).then(res4 => {
// radimo nešto
}).then(res5 => {
// radimo nešto
}).then(res6 => {
// radimo nešto
});
}
func();
Drugi problem
Postoji problem i druge prirode. Pretpostavimo sada da želimo da iskoristimo našu funkciju dva puta, a zatim da saberemo rezultate. Kao rezultat dobićemo ovakav kod:
function func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
console.log(res1 + res2); // ispisaće 13
});
});
}
func();
Već podseća na callback hell, zar ne? Dodajmo još jedan poziv funkcije - kod će postati još gori:
function func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
getSmth(4).then(res3 => {
console.log(res1 + res2 + res3);
});
});
});
}
func();
Mogli bismo, naravno, iskoristiti Promise.all:
function func() {
Promise.all([getSmth(2), getSmth(3), getSmth(4)]).then(res => {
console.log(res[0] + res[1] + res[2]);
});
}
func();
Međutim, da li smo dobili isto? Ne! U prvom slučaju svaka naredna funkcija čeka završetak prethodnog promisa, a u drugom slučaju - svi promisi se izvršavaju istovremeno. Ova razlika će biti suštinska u slučaju kada želimo da u narednu funkciju prosledimo poziv prethodne:
function func() {
getSmth(2).then(res1 => {
getSmth(res1).then(res2 => {
getSmth(res2).then(res3 => {
console.log(res3);
});
});
});
}
func();