Promise hell-problemet i JavaScript
Du vet allerede at promises ble opprettet for å løse problemet med callback hell. Men med tiden viste det seg at promises også kan skape kompleks kode. Dette problemet ble analogt kalt promise hell.
La oss se på dette problemet med kodeeksempler.
Anta at vi har en funksjon getSmth,
som tar imot en parameter og returnerer et resultat
avhengig av denne parameteren:
function getSmth(num) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(num * num), 1000)
});
}
I dette tilfellet imiterer vi en nyttig operasjon (for eksempel å hente data fra en server). Som en imitasjon sender vi bare inn et tall som en parameter og returnerer kvadratet av dette tallet etter ett sekund.
La oss nå bruke funksjonen vår
getSmth inni en annen funksjon:
function func() {
getSmth(2).then(res => {
console.log(res); // vil skrive ut 4
});
}
func();
Første problem
Mange etterfølgende
then-konstruksjoner gjør koden vanskelig å forstå:
function func(){
getSmth(2).then(res1 => {
// gjør noe
}).then(res2 => {
// gjør noe
}).then(res3 => {
// gjør noe
}).then(res4 => {
// gjør noe
}).then(res5 => {
// gjør noe
}).then(res6 => {
// gjør noe
});
}
func();
Andre problem
Det er også et problem av en annen art. Anta nå at vi ønsker å bruke funksjonen vår to ganger, og deretter summere resultatene. Som et resultat får vi denne koden:
function func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
console.log(res1 + res2); // vil skrive ut 13
});
});
}
func();
Allerede minner om callback hell, ikke sant? La oss legge til enda et funksjonskall - koden blir enda verre:
function func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
getSmth(4).then(res3 => {
console.log(res1 + res2 + res3);
});
});
});
}
func();
Vi kan selvfølgelig bruke Promise.all:
function func() {
Promise.all([getSmth(2), getSmth(3), getSmth(4)]).then(res => {
console.log(res[0] + res[1] + res[2]);
});
}
func();
Men fikk vi det samme? Nei! I det første tilfellet venter hver nye funksjon på at forrige promise skal fullføres, mens i det andre tilfellet - kjører alle promises samtidig. Denne forskjellen vil være betydelig i tilfeller der vi i den neste funksjonen ønsker å sende resultatet fra forrige kall:
function func() {
getSmth(2).then(res1 => {
getSmth(res1).then(res2 => {
getSmth(res2).then(res3 => {
console.log(res3);
});
});
});
}
func();