Problém promise hell v JavaScriptu
Už víte, že promise byly vytvořeny za účelem vyřešení problému callback hell. Postupem času se však ukázalo, že promise také mohou vytvářet složitý kód. Tento problém byl analogicky nazván promise hell.
Pojďme se na tento problém podívat na příkladech
kódu. Předpokládejme, že máme funkci getSmth,
která přijímá parametr a vrací výsledek
v závislosti na tomto parametru:
function getSmth(num) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(num * num), 1000)
});
}
V tomto případě simulujeme nějakou užitečnou operaci (například získání dat ze serveru). Jako simulaci jednoduše předáme číslo jako parametr a po vteřině vrátíme druhou mocninu tohoto čísla.
Nyní použijme naši funkci
getSmth uvnitř jiné funkce:
function func() {
getSmth(2).then(res => {
console.log(res); // vypíše 4
});
}
func();
První problém
Mnoho konstrukcí then následujících po sobě
znesnadňuje pochopení kódu:
function func(){
getSmth(2).then(res1 => {
// děláme něco
}).then(res2 => {
// děláme něco
}).then(res3 => {
// děláme něco
}).then(res4 => {
// děláme něco
}).then(res5 => {
// děláme něco
}).then(res6 => {
// děláme něco
});
}
func();
Druhý problém
Existuje problém i jiného druhu. Předpokládejme nyní, že chceme použít naši funkci dvakrát a poté sečíst výsledky. Ve výsledku dostaneme takovýto kód:
function func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
console.log(res1 + res2); // vypíše 13
});
});
}
func();
Už to připomíná callback hell, že? Přidejme ještě jedno volání funkce - kód se stane ještě horším:
function func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
getSmth(4).then(res3 => {
console.log(res1 + res2 + res3);
});
});
});
}
func();
Lze samozřejmě použít Promise.all:
function func() {
Promise.all([getSmth(2), getSmth(3), getSmth(4)]).then(res => {
console.log(res[0] + res[1] + res[2]);
});
}
func();
Ale dostali jsme to samé? Ne! V prvním případě každá nová funkce čeká na dokončení předchozího promise, zatímco ve druhém případě - všechny promise se vykonávají současně. Tento rozdíl bude podstatný v případě, kdy budeme chtít do další funkce předat výsledek volání předchozí:
function func() {
getSmth(2).then(res1 => {
getSmth(res1).then(res2 => {
getSmth(res2).then(res3 => {
console.log(res3);
});
});
});
}
func();