Das Problem des Promise Hell in JavaScript
Sie wissen bereits, dass Promises erstellt wurden, um das Problem des Callback Hell zu lösen. Allerdings hat sich mit der Zeit herausgestellt, dass Promises auch komplexen Code erzeugen können. Dieses Problem wurde analog als promise hell bezeichnet.
Lassen Sie uns dieses Problem anhand von Codebeispielen
betrachten. Angenommen, wir haben eine Funktion getSmth,
die einen Parameter erhält und ein Ergebnis
in Abhängigkeit von diesem Parameter zurückgibt:
function getSmth(num) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(num * num), 1000)
});
}
In diesem Fall imitieren wir eine nützliche Operation (z. B. das Abrufen von Daten von einem Server). Zur Simulation übergeben wir einfach eine Zahl als Parameter und geben nach einer Sekunde das Quadrat dieser Zahl zurück.
Lassen Sie uns nun unsere Funktion
getSmth innerhalb einer anderen Funktion verwenden:
function func() {
getSmth(2).then(res => {
console.log(res); // gibt 4 aus
});
}
func();
Erstes Problem
Mehrere aufeinanderfolgende
then Konstrukte erschweren das Verständnis des Codes:
function func(){
getSmth(2).then(res1 => {
// tun wir etwas
}).then(res2 => {
// tun wir etwas
}).then(res3 => {
// tun wir etwas
}).then(res4 => {
// tun wir etwas
}).then(res5 => {
// tun wir etwas
}).then(res6 => {
// tun wir etwas
});
}
func();
Zweites Problem
Es gibt auch ein Problem anderer Art. Nehmen wir nun an, wir möchten unsere Funktion zweimal verwenden und dann die Ergebnisse summieren. Daraus ergibt sich folgender Code:
function func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
console.log(res1 + res2); // gibt 13 aus
});
});
}
func();
Erinnert schon an Callback Hell, nicht wahr? Fügen wir noch einen Funktionsaufruf hinzu - der Code wird noch schlimmer:
function func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
getSmth(4).then(res3 => {
console.log(res1 + res2 + res3);
});
});
});
}
func();
Man könnte natürlich Promise.all verwenden:
function func() {
Promise.all([getSmth(2), getSmth(3), getSmth(4)]).then(res => {
console.log(res[0] + res[1] + res[2]);
});
}
func();
Aber haben wir damit dasselbe erreicht? Nein! Im ersten Fall wartet jede neue Funktion auf das Abschließen des vorherigen Promises, während im zweiten Fall alle Promises gleichzeitig ausgeführt werden. Dieser Unterschied ist wesentlich, wenn wir in die nächste Funktion den Aufruf der vorherigen übergeben wollen:
function func() {
getSmth(2).then(res1 => {
getSmth(res1).then(res2 => {
getSmth(res2).then(res3 => {
console.log(res3);
});
});
});
}
func();