JavaScript-ում promise hell-ի խնդիրը

Դուք արդեն գիտեք, որ promise-ները ստեղծվել էին callback hell-ի խնդիրը լուծելու համար: Սակայն, ժամանակի ընթացքում պարզ դարձավ, որ promise-ները նույնպես կարող են բարդ կոդ առաջացնել: Այս խնդիրը անալոգիայով կոչվեց promise hell։

Եկեք դիտարկենք այս խնդիրը կոդի օրինակներով: Ենթադրենք ունենք getSmth ֆունկցիան, որը ստանում է պարամետր և վերադարձնում արդյունք կախված այդ պարամետրից:

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

Այս դեպքում մենք իմիտացնում ենք որոշակի օգտակար գործողություն (օրինակ, սերվերից տվյալներ ստանալը): Իմիտացիայի համար մենք պարզապես պարամետրով փոխանցում ենք թիվ և մեկ վայրկյան հետո վերադարձնում այդ թվի քառակուսին:

Եկեք հիմա օգտագործենք մեր getSmth ֆունկցիան մեկ այլ ֆունկցիայի ներսում:

javascriptfunction func() {
  getSmth(2).then(res => {
    console.log(res); // կարտածի 4
  });
}

func();

Առաջին խնդիրը

Միմյանց հաջորդող then կոնստրուկցիաների բազմությունը դժվարացնում է կոդի ընկալումը:

javascriptfunction func(){
  getSmth(2).then(res1 => {
    // ինչ-որ բան անում ենք
  }).then(res2 => {
    // ինչ-որ բան անում ենք
  }).then(res3 => {
    // ինչ-որ բան անում ենք
  }).then(res4 => {
    // ինչ-որ բան անում ենք
  }).then(res5 => {
    // ինչ-որ բան անում ենք
  }).then(res6 => {
    // ինչ-որ բան անում ենք
  });
}

func();

Երկրորդ խնդիրը

Գոյություն ունի նաև այլ բնույթի խնդիր: Ենթադրենք հիմա մենք ցանկանում ենք օգտագործել մեր ֆունկցիան երկու անգամ, ապա գումարել արդյունքները: Արդյունքում մենք կստանանք այսպիսի կոդ:

javascriptfunction func() {
  getSmth(2).then(res1 => {
    getSmth(3).then(res2 => {
      console.log(res1 + res2); // կարտածի 13
    });
  });
}

func();

Արդեն հիշեցնում է callback hell, այնպես չէ՞: Ավելացնենք ևս մեկ ֆունկցիայի կանչ - կոդը կդառնա ավելի վատ:

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

func();

Կարելի է, իհարկե, օգտագործել Promise.all-ը:

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

func();

Սակայն, արդյո՞ք ստացանք նույն բանը: Ոչ: Առաջին դեպքում յուրաքանչյուր նոր ֆունկցիա սպասում է նախորդ promise-ի ավարտին, իսկ երկրորդ դեպքում - բոլոր promise-ները կատարվում են միաժամանակ: Այս տարբերությունը էական կլինի այն դեպքում, երբ մենք հաջորդ ֆունկցիային ցանկանանք փոխանցել նախորդի կանչի արդյունքը:

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

func();