Promise hell problēma JavaScript
Jūs jau zināt, ka promise tika izveidoti, lai atrisinātu callback hell problēmu. Tomēr, laika gaitā izrādījās, ka promise arī spēj radīt sarežģītu kodu. Šī problēma pēc analoģijas tika nosaukta par promise hell.
Apskatīsim šo problēmu ar kodu piemēriem.
Pieņemsim, ka mums ir funkcija getSmth,
kas saņem parametru un atgriež rezultātu
atkarībā no šī parametra:
function getSmth(num) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(num * num), 1000)
});
}
Šajā gadījumā mēs imitējam kādu noderīgu darbību (piemēram, datu iegūšanu no servera). Kā imitāciju mēs vienkārši padodam skaitli kā parametru un pēc sekundes atgriežam šī skaitļa kvadrātu.
Tagad izmantosim mūsu funkciju
getSmth citas funkcijas iekšienē:
function func() {
getSmth(2).then(res => {
console.log(res); // izvadīs 4
});
}
func();
Pirmā problēma
Vairākas viena pēc otras sekojošas konstrukcijas
then apgrūtina koda izpratni:
function func(){
getSmth(2).then(res1 => {
// darām kaut ko
}).then(res2 => {
// darām kaut ko
}).then(res3 => {
// darām kaut ko
}).then(res4 => {
// darām kaut ko
}).then(res5 => {
// darām kaut ko
}).then(res6 => {
// darām kaut ko
});
}
func();
Otrā problēma
Ir arī cita veida problēma. Pieņemsim, ka tagad mēs vēlamies izmantot mūsu funkciju divas reizes, tad saskaitīt rezultātus. Rezultātā mēs iegūsim šādu kodu:
function func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
console.log(res1 + res2); // izvadīs 13
});
});
}
func();
Jau atgādina callback hell, vai ne? Pievienosim vēl vienu funkcijas izsaukumu - kods kļūs vēl sliktāks:
function func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
getSmth(4).then(res3 => {
console.log(res1 + res2 + res3);
});
});
});
}
func();
Var, protams, izmantot Promise.all:
function func() {
Promise.all([getSmth(2), getSmth(3), getSmth(4)]).then(res => {
console.log(res[0] + res[1] + res[2]);
});
}
func();
Tomēr, vai mēs ieguvām to pašu? Nē! Pirmajā gadījumā katra nākamā funkcija gaida iepriekšējā promise pabeigšanos, bet otrajā gadījumā - visi promise tiek izpildīti vienlaicīgi. Šī atšķirība būs būtiska gadījumā, kad mēs nākamajā funkcijā vēlēsimies padot iepriekšējās izsaukumu:
function func() {
getSmth(2).then(res1 => {
getSmth(res1).then(res2 => {
getSmth(res2).then(res3 => {
console.log(res3);
});
});
});
}
func();