Problemi i promise hell në JavaScript
Ju tashmë e dini se promiset u krijuan për të zgjidhur problemin e callback hell. Sidoqoftë, me kalimin e kohës doli se promiset gjithashtu janë të afta të krijojnë kod kompleks. Ky problem me analogji u quajt promise hell.
Le ta shqyrtojmë këtë problem me shembuj
kodi. Le të themi se kemi funksionin getSmth,
i cili merr një parametër dhe kthen rezultatin
në varësi të atij parametri:
function getSmth(num) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(num * num), 1000)
});
}
Në këtë rast ne po imitojmë një operacion të dobishëm (për shembull, marrjen e të dhënave nga serveri). Si imitim ne thjesht e kalojmë numrin si parametër dhe pas një sekonde kthejmë katrorin e atij numri.
Tani le të përdorim funksionin tonë
getSmth brenda një funksioni tjetër:
function func() {
getSmth(2).then(res => {
console.log(res); // do të shfaqë 4
});
}
func();
Problemi i parë
Shumë konstrukte then
që ndjekin njëra-tjetrën e bëjnë të vështirë kuptimin e kodit:
function func(){
getSmth(2).then(res1 => {
// bëjmë diçka
}).then(res2 => {
// bëjmë diçka
}).then(res3 => {
// bëjmë diçka
}).then(res4 => {
// bëjmë diçka
}).then(res5 => {
// bëjmë diçka
}).then(res6 => {
// bëjmë diçka
});
}
func();
Problemi i dytë
Ekziston një problem tjetër. Le të themi tani se duam të përdorim funksionin tonë dy herë, pastaj të mbledhim rezultatet. Si rezultat do të kemi këtë kod:
function func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
console.log(res1 + res2); // do të shfaqë 13
});
});
}
func();
Tashmë të kujton callback hell, apo jo? Le të shtojmë edhe një thirrje funksioni - kodi do të bëhet edhe më i keq:
function func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
getSmth(4).then(res3 => {
console.log(res1 + res2 + res3);
});
});
});
}
func();
Mundet, sigurisht, të përdoret Promise.all:
function func() {
Promise.all([getSmth(2), getSmth(3), getSmth(4)]).then(res => {
console.log(res[0] + res[1] + res[2]);
});
}
func();
Sidoqoftë, a morëm të njëjtën gjë? Jo! Në rastin e parë çdo funksion i ri pret përfundimin e promise-it të mëparshëm, ndërsa në të dytin rast - të gjitha promiset ekzekutohen njëkohësisht. Ky ndryshim do të jetë i rëndësishëm në rastin kur në funksionin tjetër duam të kalojmë rezultatin e thirrjes së mëparshme:
function func() {
getSmth(2).then(res1 => {
getSmth(res1).then(res2 => {
getSmth(res2).then(res3 => {
console.log(res3);
});
});
});
}
func();