Problem promise hell-a u JavaScript-u

Već znate da su promisi stvoreni da reše problem callback hell-a. Međutim, vremenom se pokazalo da promisi takođe mogu stvoriti složen kod. Ovaj problem je po analogiji nazvan promise hell.

Hajde da razmotrimo ovaj problem na primerima koda. Pretpostavimo da imamo funkciju getSmth, koja prima parametar i vraća rezultat zavisno od tog parametra:

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

U ovom slučaju imitirajmo neku korisnu operaciju (na primer, preuzimanje podataka sa servera). Kao imitaciju, jednostavno prosledimo broj kao parametar i za sekundu vratimo kvadrat tog broja.

Sada hajde da iskoristimo našu funkciju getSmth unutar druge funkcije:

javascriptfunction func() {
  getSmth(2).then(res => {
    console.log(res); // ispisaće 4
  });
}

func();

Prvi problem

Brojne konstrukcije then koje se jedna za drugom javljaju, otežavaju razumevanje koda:

javascriptfunction func(){
  getSmth(2).then(res1 => {
    // radimo nešto
  }).then(res2 => {
    // radimo nešto
  }).then(res3 => {
    // radimo nešto
  }).then(res4 => {
    // radimo nešto
  }).then(res5 => {
    // radimo nešto
  }).then(res6 => {
    // radimo nešto
  });
}

func();

Drugi problem

Postoji problem i druge prirode. Pretpostavimo sada da želimo da iskoristimo našu funkciju dva puta, a zatim da saberemo rezultate. Kao rezultat dobićemo ovakav kod:

javascriptfunction func() {
  getSmth(2).then(res1 => {
    getSmth(3).then(res2 => {
      console.log(res1 + res2); // ispisaće 13
    });
  });
}

func();

Već podseća na callback hell, zar ne? Dodajmo još jedan poziv funkcije - kod će postati još gori:

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

func();

Mogli bismo, naravno, iskoristiti Promise.all:

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

func();

Međutim, da li smo dobili isto? Ne! U prvom slučaju svaka naredna funkcija čeka završetak prethodnog promisa, a u drugom slučaju - svi promisi se izvršavaju istovremeno. Ova razlika će biti suštinska u slučaju kada želimo da u narednu funkciju prosledimo poziv prethodne:

javascriptfunction func() {
  getSmth(2).then(res1 => {
    getSmth(res1).then(res2 => {
      getSmth(res2).then(res3 => {
        console.log(res3);
      });
    });
  });
}

func();