Promise hell problemet i JavaScript
Du ved allerede, at promises blev opfundet for at løse callback hell problemet. Men med tiden viste det sig, at promises også kan skabe kompleks kode. Dette problem blev analogt kaldt promise hell.
Lad os se på dette problem med kodeeksempler.
Antag, at vi har en funktion getSmth,
der modtager en parameter og returnerer et resultat
afhængigt af denne parameter:
function getSmth(num) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(num * num), 1000)
});
}
I dette tilfælde efterligner vi en nyttig operation (for eksempel at hente data fra en server). Som en simulering sender vi blot et tal som parameter og returnerer kvadratet på dette tal efter et sekund.
Lad os nu bruge vores funktion
getSmth inde i en anden funktion:
function func() {
getSmth(2).then(res => {
console.log(res); // vil udskrive 4
});
}
func();
Første problem
Mange then konstruktioner i træk
gør koden vanskelig at forstå:
function func(){
getSmth(2).then(res1 => {
// gør noget
}).then(res2 => {
// gør noget
}).then(res3 => {
// gør noget
}).then(res4 => {
// gør noget
}).then(res5 => {
// gør noget
}).then(res6 => {
// gør noget
});
}
func();
Andet problem
Der er også et problem af en anden art. Antag nu, at vi ønsker at bruge vores funktion to gange og derefter summere resultaterne. Som følge heraf får vi denne kode:
function func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
console.log(res1 + res2); // vil udskrive 13
});
});
}
func();
Det minder allerede om callback hell, ikke? Lad os tilføje endnu et kald til funktionen - koden bliver endnu værre:
function func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
getSmth(4).then(res3 => {
console.log(res1 + res2 + res3);
});
});
});
}
func();
Man kunne selvfølgelig bruge Promise.all:
function func() {
Promise.all([getSmth(2), getSmth(3), getSmth(4)]).then(res => {
console.log(res[0] + res[1] + res[2]);
});
}
func();
Men fik vi det samme? Nej! I det første tilfælde venter hver nye funktion på, at den forrige promise afsluttes, mens i det andet tilfælde udføres alle promises samtidigt. Denne forskel vil være væsentlig i det tilfælde, hvor vi i den næste funktion ønsker at videregive resultatet fra det foregående kald:
function func() {
getSmth(2).then(res1 => {
getSmth(res1).then(res2 => {
getSmth(res2).then(res3 => {
console.log(res3);
});
});
});
}
func();