Promise hell-problemet i JavaScript
Du vet redan att löften skapades för att lösa problemet med callback hell. Men med tiden visade det sig att löften också kan generera komplex kod. Detta problem kallades i analogi promise hell.
Låt oss överväga detta problem med kodexempel.
Låt oss säga att vi har en funktion getSmth,
som tar en parameter och returnerar ett resultat
beroende på den parametern:
javascriptfunction getSmth(num) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(num * num), 1000)
});
}
I det här fallet imiterar vi en användbar operation (till exempel att hämta data från en server). Som en imitation skickar vi helt enkelt ett nummer som en parameter och returnerar kvadraten på det numret efter en sekund.
Låt oss nu använda vår funktion
getSmth inuti en annan funktion:
javascriptfunction func() {
getSmth(2).then(res => {
console.log(res); // skriver ut 4
});
}
func();
Första problemet
Flera then-konstruktioner i följd
gör koden svårläst:
javascriptfunction func(){
getSmth(2).then(res1 => {
// gör något
}).then(res2 => {
// gör något
}).then(res3 => {
// gör något
}).then(res4 => {
// gör något
}).then(res5 => {
// gör något
}).then(res6 => {
// gör något
});
}
func();
Andra problemet
Det finns ett problem av ett annat slag. Låt oss nu säga att vi vill använda vår funktion två gånger och sedan summera resultaten. Som ett resultat får vi den här koden:
javascriptfunction func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
console.log(res1 + res2); // skriver ut 13
});
});
}
func();
Påminner redan om callback hell, eller hur? Låt oss lägga till ytterligare ett funktionsanrop - koden blir ännu värre:
javascriptfunction func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
getSmth(4).then(res3 => {
console.log(res1 + res2 + res3);
});
});
});
}
func();
Man kan förstås använda Promise.all:
javascriptfunction func() {
Promise.all([getSmth(2), getSmth(3), getSmth(4)]).then(res => {
console.log(res[0] + res[1] + res[2]);
});
}
func();
Men fick vi samma sak? Nej! I det första fallet väntar varje ny funktion tills det föregående löftet är klart, medan i det andra fallet - alla löften utförs samtidigt. Denna skillnad kommer att vara väsentlig i det fall där vi vill skicka resultatet från det föregående anropet till nästa funktion:
javascriptfunction func() {
getSmth(2).then(res1 => {
getSmth(res1).then(res2 => {
getSmth(res2).then(res3 => {
console.log(res3);
});
});
});
}
func();