Promise hell problema JavaScript
Jūs jau žinote, kad promisai buvo sukurti tam, kad išspręstų callback hell problemą. Tačiau, laikui bėgant paaiškėjo, kad promisai taip pat gali sukurti sudėtingą kodą. Ši problema pagal analogiją buvo pavadinta promise hell.
Pažvelkime į šią problemą kodo pavyzdžiuose.
Tarkime, kad turime funkciją getSmth,
kuri gauna parametrą ir grąžina rezultatą
priklausomai nuo šio parametro:
function getSmth(num) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(num * num), 1000)
});
}
Šiuo atveju mes imituojame tam tikrą naudingą operaciją (pavyzdžiui, duomenų gavimą iš serverio). Kaip imitaciją mes tiesiog parametru perduodame skaičių ir po sekundės grąžiname šio skaičiaus kvadratą.
Dabar panaudokime mūsų funkciją
getSmth kitoje funkcijoje:
function func() {
getSmth(2).then(res => {
console.log(res); // išves 4
});
}
func();
Pirmoji problema
Daugybė vieną po kitos einančių konstrukcijų
then apsunkina kodo supratimą:
function func(){
getSmth(2).then(res1 => {
// darome ką nors
}).then(res2 => {
// darome ką nors
}).then(res3 => {
// darome ką nors
}).then(res4 => {
// darome ką nors
}).then(res5 => {
// darome ką nors
}).then(res6 => {
// darome ką nors
});
}
func();
Antroji problema
Yra ir kitokio pobūdžio problema. Tarkime, kad dabar mes norime panaudoti mūsų funkciją du kartus, o tada susumuoti rezultatus. Rezultate gausime tokį kodą:
function func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
console.log(res1 + res2); // išves 13
});
});
}
func();
Jau primena callback hell, ar ne? Pridėkime dar vieną funkcijos iškvietimą - kodas taps dar blogesnis:
function func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
getSmth(4).then(res3 => {
console.log(res1 + res2 + res3);
});
});
});
}
func();
Galima, žinoma, panaudoti Promise.all:
function func() {
Promise.all([getSmth(2), getSmth(3), getSmth(4)]).then(res => {
console.log(res[0] + res[1] + res[2]);
});
}
func();
Tačiau, ar gavome tą patį? Ne! Pirmuoju atveju kiekviena nauja funkcija laukia ankstesnio promiso užbaigimo, o antruoju atveju - visi promisai vykdomi vienu metu. Šis skirtumas bus reikšmingas tuo atveju, kai mes į sekanti funkciją norėsime perduoti ankstesnės iškvietimą:
function func() {
getSmth(2).then(res1 => {
getSmth(res1).then(res2 => {
getSmth(res2).then(res3 => {
console.log(res3);
});
});
});
}
func();