Problemi i promise hell në JavaScript

Ju tashmë e dini se promiset u krijuan për të zgjidhur problemin e callback hell. Sidoqoftë, me kalimin e kohës doli se promiset gjithashtu janë të afta të krijojnë kod kompleks. Ky problem me analogji u quajt promise hell.

Le ta shqyrtojmë këtë problem me shembuj kodi. Le të themi se kemi funksionin getSmth, i cili merr një parametër dhe kthen rezultatin në varësi të atij parametri:

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

Në këtë rast ne po imitojmë një operacion të dobishëm (për shembull, marrjen e të dhënave nga serveri). Si imitim ne thjesht e kalojmë numrin si parametër dhe pas një sekonde kthejmë katrorin e atij numri.

Tani le të përdorim funksionin tonë getSmth brenda një funksioni tjetër:

javascriptfunction func() {
  getSmth(2).then(res => {
    console.log(res); // do të shfaqë 4
  });
}

func();

Problemi i parë

Shumë konstrukte then që ndjekin njëra-tjetrën e bëjnë të vështirë kuptimin e kodit:

javascriptfunction func(){
  getSmth(2).then(res1 => {
    // bëjmë diçka
  }).then(res2 => {
    // bëjmë diçka
  }).then(res3 => {
    // bëjmë diçka
  }).then(res4 => {
    // bëjmë diçka
  }).then(res5 => {
    // bëjmë diçka
  }).then(res6 => {
    // bëjmë diçka
  });
}

func();

Problemi i dytë

Ekziston një problem tjetër. Le të themi tani se duam të përdorim funksionin tonë dy herë, pastaj të mbledhim rezultatet. Si rezultat do të kemi këtë kod:

javascriptfunction func() {
  getSmth(2).then(res1 => {
    getSmth(3).then(res2 => {
      console.log(res1 + res2); // do të shfaqë 13
    });
  });
}

func();

Tashmë të kujton callback hell, apo jo? Le të shtojmë edhe një thirrje funksioni - kodi do të bëhet edhe më i keq:

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

func();

Mundet, sigurisht, të përdoret Promise.all:

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

func();

Sidoqoftë, a morëm të njëjtën gjë? Jo! Në rastin e parë çdo funksion i ri pret përfundimin e promise-it të mëparshëm, ndërsa në të dytin rast - të gjitha promiset ekzekutohen njëkohësisht. Ky ndryshim do të jetë i rëndësishëm në rastin kur në funksionin tjetër duam të kalojmë rezultatin e thirrjes së mëparshme:

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

func();