⊗jsSpPrmPH 173 of 294 menu

Promise hell -ongelman JavaScriptissä

Tiedät jo, että promiset luotiin ratkaisemaan callback hell -ongelma. Kuitenkin ajan myötä kävi ilmi, että promiset voivat myös synnyttää monimutkaista koodia. Tätä ongelmaa kutsutaan analogisesti nimellä promise hell.

Tarkastellaan tätä ongelmaa koodiesimerkkien avulla. Oletetaan, että meillä on funktio getSmth, joka saa parametrin ja palauttaa tuloksen riippuen tästä parametristä:

function getSmth(num) { return new Promise((resolve, reject) => { setTimeout(() => resolve(num * num), 1000) }); }

Tässä tapauksessa imitoimme jotain hyödyllistä toimintoa (esimerkiksi tietojen hakemista palvelimelta). Imitaationa välitämme parametrina yksinkertaisesti luvun ja palautamme sekunnin kuluttua sen neliön.

Hyödynnetään nyt funktiotamme getSmth toisen funktion sisällä:

function func() { getSmth(2).then(res => { console.log(res); // tulostaa 4 }); } func();

Ensimmäinen ongelma

Useat peräkkäiset then -rakenteet vaikeuttavat koodin ymmärtämistä:

function func(){ getSmth(2).then(res1 => { // teemme jotain }).then(res2 => { // teemme jotain }).then(res3 => { // teemme jotain }).then(res4 => { // teemme jotain }).then(res5 => { // teemme jotain }).then(res6 => { // teemme jotain }); } func();

Toinen ongelma

On olemassa toisenlainen ongelma. Oletetaan nyt, että haluamme hyödyntää funktiotamme kaksi kertaa ja laskea tulokset yhteen. Tuloksena saamme tällaisen koodin:

function func() { getSmth(2).then(res1 => { getSmth(3).then(res2 => { console.log(res1 + res2); // tulostaa 13 }); }); } func();

Muistuttaa jo callback helliä, eikö vain? Lisätään vielä yksi funktiokutsu - koodista tulee vielä huonompi:

function func() { getSmth(2).then(res1 => { getSmth(3).then(res2 => { getSmth(4).then(res3 => { console.log(res1 + res2 + res3); }); }); }); } func();

Voisimme tietysti hyödyntää Promise.all:

function func() { Promise.all([getSmth(2), getSmth(3), getSmth(4)]).then(res => { console.log(res[0] + res[1] + res[2]); }); } func();

Mutta saimmeko saman tuloksen? Ei! Ensimmäisessä tapauksessa jokainen uusi funktio odottaa edellisen promisen valmistumista, kun taas toisessa tapauksessa - kaikki promiset suoritetaan samanaikaisesti. Tämä ero on merkittävä silloin, kun haluamme välittää seuraavaan funktioon edellisen funktion tuloksen:

function func() { getSmth(2).then(res1 => { getSmth(res1).then(res2 => { getSmth(res2).then(res3 => { console.log(res3); }); }); }); } func();
Suomi
AfrikaansAzərbaycanБългарскиবাংলাБеларускаяČeštinaDanskDeutschΕλληνικάEnglishEspañolEestiFrançaisहिन्दीMagyarՀայերենIndonesiaItaliano日本語ქართულიҚазақ한국어КыргызчаLietuviųLatviešuМакедонскиMelayuမြန်မာNederlandsNorskPolskiPortuguêsRomânăРусскийසිංහලSlovenčinaSlovenščinaShqipСрпскиSrpskiSvenskaKiswahiliТоҷикӣไทยTürkmenTürkçeЎзбекOʻzbekTiếng Việt
Käytämme evästeitä verkkosivuston toiminnalle, analytiikalle ja personoinnille. Tietojen käsittely tapahtuu Tietosuojakäytännön mukaisesti.
hyväksy kaikki mukauta hylkää